Suche…


grundlegende Verwendungen von Schutzklauseln

In Elixir kann man mehrere Implementierungen einer Funktion mit demselben Namen erstellen und Regeln festlegen, die auf die Parameter der Funktion angewendet werden, bevor die Funktion aufgerufen wird, um zu bestimmen, welche Implementierung ausgeführt werden soll.

Diese Regeln werden durch das Schlüsselwort when markiert und def function_name(params) do in der Funktionsdefinition zwischen def function_name(params) und do . Ein triviales Beispiel:

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

Math.is_even(2) ich Math.is_even(2) mit diesem Beispiel Math.is_even(2) . Es gibt zwei Implementierungen von is_even mit unterschiedlichen Guard-Klauseln. Das System prüft sie der Reihe nach und führt die erste Implementierung aus, bei der die Parameter die Guard-Klausel erfüllen. Der erste gibt an, dass num === 1 nicht wahr ist, also geht es zum nächsten weiter. Die zweite gibt an, dass num === 2 , was wahr ist. Dies ist also die verwendete Implementierung, und der Rückgabewert ist true .

Was ist, wenn ich Math.is_odd(1) ? Das System betrachtet die erste Implementierung und stellt fest, dass seit num 1 die Schutzklausel der ersten Implementierung erfüllt ist. Es wird dann diese Implementierung verwenden und true , ohne sich um andere Implementierungen zu kümmern.

Wachen sind in den Arten von Operationen, die sie ausführen können, eingeschränkt. Die Elixir-Dokumentation listet jede zulässige Operation auf . is_atom gesagt, sie ermöglichen Vergleiche, mathematische Operationen, binäre Operationen, Typprüfungen (z. B. is_atom ) und eine Handvoll kleiner Komfortfunktionen (z. B. length ). Es ist möglich, benutzerdefinierte Schutzklauseln zu definieren, es erfordert jedoch das Erstellen von Makros und sollte am besten für eine erweiterte Anleitung verwendet werden.


Beachten Sie, dass Wachen keine Fehler werfen. Sie werden als normale Fehler der Guard-Klausel behandelt, und das System betrachtet die nächste Implementierung. Wenn Sie feststellen, dass Sie (FunctionClauseError) no function clause matching wenn Sie eine überwachte Funktion mit den von Ihnen erwarteten Params aufrufen, kann es sein, dass eine von Ihnen erwartete Guard-Klausel einen Fehler ausgibt, der verschluckt wird.

Um dies für sich selbst zu sehen, erstellen Sie eine Funktion und rufen Sie sie dann mit einem Wächter auf, der keinen Sinn hat, wie z. B. dieser, die versucht, durch Null zu teilen:

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

Durch den Aufruf von BadMath.divide("anything") wird der etwas wenig hilfreiche Fehler (FunctionClauseError) no function clause matching in BadMath.divide/1 Wenn Sie jedoch versucht haben, "anything" / 0 direkt auszuführen, erhalten Sie hilfreiche (FunctionClauseError) no function clause matching in BadMath.divide/1 Fehler: (ArithmeticError) bad argument in arithmetic expression .



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow