Elixir Language
grundlegende Verwendung von Schutzklauseln
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
.