Szukaj…


podstawowe zastosowania klauzul ochronnych

W Elixir można utworzyć wiele implementacji funkcji o tej samej nazwie i określić reguły, które zostaną zastosowane do parametrów funkcji przed wywołaniem funkcji w celu ustalenia, która implementacja ma zostać uruchomiona.

Reguły te są oznaczone słowem kluczowym when i idą między def function_name(params) a do w definicji funkcji. Trywialny przykład:

defmodule Math do

  def is_even(num) when num === 1 do
    false
  end
  def is_even(num) when num === 2 do
    true
  end

  def is_odd(num) when num === 1 do
    true
  end
  def is_odd(num) when num === 2 do
    false
  end

end

Załóżmy, że uruchamiam Math.is_even(2) tym przykładzie. Istnieją dwie implementacje is_even , z różnymi klauzulami ochronnymi. System obejrzy je w kolejności i uruchomi pierwszą implementację, w której parametry spełniają klauzulę ochronną. Pierwszy określa, że num === 1 co nie jest prawdą, więc przechodzi do następnego. Drugi określa, że num === 2 , co jest prawdą, więc jest to implementacja używana, a zwracana wartość będzie true .

Co się stanie, jeśli uruchomię Math.is_odd(1) ? Wygląd systemu w pierwszej realizacji i widzi, że od num jest 1 klauzula osłona od pierwszego wdrożenia jest spełniony. Następnie użyje tej implementacji i zwróci wartość true , nie zawracając sobie głowy przyglądaniem się innym implementacjom.

Strażnicy mają ograniczone rodzaje operacji, jakie mogą wykonywać. Dokumentacja Elixir zawiera wszystkie dozwolone operacje ; w skrócie pozwalają na porównania, matematykę, operacje binarne, sprawdzanie typu (np. is_atom ) i garść małych funkcji wygody (np. length ). Możliwe jest zdefiniowanie niestandardowych klauzul ochronnych, ale wymaga ono tworzenia makr i najlepiej pozostawić bardziej zaawansowany przewodnik.


Pamiętaj, że strażnicy nie zgłaszają błędów; są one traktowane jako normalne awarie klauzuli ochronnej, a system przechodzi do następnej implementacji. Jeśli okaże się, że otrzymujesz (FunctionClauseError) no function clause matching podczas wywoływania funkcji strzeżonej z parametrami, których działania oczekujesz, może być tak, że klauzula ochronna, której działania oczekujesz, generuje błąd, który jest połykany.

Aby to zobaczyć, utwórz, a następnie wywołaj funkcję ze strażnikiem, która nie ma sensu, na przykład ta, która próbuje podzielić przez zero:

defmodule BadMath do
  def divide(a) when a / 0 === :foo do
    :bar
  end
end

Wywołanie BadMath.divide("anything") zapewni nieco niepomocny błąd (FunctionClauseError) no function clause matching in BadMath.divide/1 - podczas gdy gdybyś próbował uruchomić "anything" / 0 bezpośrednio, uzyskałbyś większą pomoc error: (ArithmeticError) bad argument in arithmetic expression .



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow