Эликсир: паттерн или страж

Мне любопытно, когда при определении функций я должен использовать сопоставление шаблонов vs guard.

Например, при сопоставлении с образцом:

defmodule Exponent do
  def power(value, 0), do: 1
  def power(value, n), do: value*power(value, n-1)
end

vs guard:

defmodule Exponent do
  def power(value, n) when n==0, do: 1
  def power(value, n), do: value*power(value, n-1)
end

Я имею в виду, что оба продукта дают одинаковый результат, но одно решение предпочтительнее другого? И если да, то почему?

Я новичок в Elixir, поэтому ответ на этот вопрос мне не совсем понятен (пока). Спасибо заранее.

Ответ 1

Гвардии более мощные, чем сопоставление с образцами, но они представляют собой сложный слой, который может оказаться ненужным. Для простых проверок равенства, как в вашем примере, они должны быть эквивалентны с точки зрения производительности. Я рекомендую сначала использовать совпадение шаблонов, чтобы все было просто. Затем вы можете вернуться к пункту охраны, если это абсолютно необходимо. Тем не менее, иногда может иметь смысл делать это иначе, когда это облегчает читаемость, например.

def sign(x) when x  < 0, do: -1
def sign(x) when x == 0, do:  0
def sign(x) when x  > 0, do:  1

Я полагаю, что "правильный" прецедент для оператора равенства в сторожевых предложениях - это когда он используется как часть более сложных выражений, например

def divisible?(x, divisor) when rem(x, divisor) == 0, do: true
def divisible?(_x, _divisor), do: false