Elixir Language
ガード句の基本的な使用
サーチ…
ガード句の基本的な使い方
Elixirでは、同じ名前の関数の複数の実装を作成し、どの実装を実行するかを決定するために関数を呼び出す前に関数のパラメータに適用される規則を指定することができます。
これらのルールはキーワードwhen
でマークされ、 def function_name(params)
と関数定義のdo
に入ります。簡単な例:
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)
を実行するとします。 is_even
には、ガード句が異なる2つの実装があります。システムはそれらを順番に調べ、パラメータがガード句を満たす最初の実装を実行します。最初のものは、 num === 1
が真ではないので、次のものに移ります。 2つ目はnum === 2
指定します。これはtrueです。これは使用される実装であり、戻り値はtrue
になりtrue
。
Math.is_odd(1)
を実行するとどうなりますか?システムは最初の実装を見て、 num
が1
あるため、最初の実装のガード節が満たされていることを確認します。その実装を使用してtrue
を返し、他の実装を気にする必要はありません。
ガードは、実行できる操作の種類が限られています。 Elixirのドキュメントには、許可されたすべての操作がリストされています簡単に言えば、比較、数学、バイナリ演算、型チェック( is_atom
)、小さな便利機能(例: length
)を可能にします。カスタムガード句を定義することは可能ですが、マクロを作成する必要があります。
ガードはエラーを投げないことに注意してください。それらはガード節の通常の失敗として扱われ、システムは次の実装を見るために移動します。あなたが期待しているparamsで保護された関数を呼び出すときに(FunctionClauseError) no function clause matching
ことがわかった場合は、動作すると予想されるガード節が飲み込まれているエラーを投げている可能性があります。
これを自分自身で見るには、ガードを持つ関数を作成して呼び出してください。この関数は、0で割り切ろうとします。
defmodule BadMath do
def divide(a) when a / 0 === :foo do
:bar
end
end
BadMath.divide("anything")
を呼び出すと(FunctionClauseError) no function clause matching in BadMath.divide/1
が多少役に立たないエラー(FunctionClauseError) no function clause matching in BadMath.divide/1
ます。一方、 "anything" / 0
直接実行しようとすると、エラー: (ArithmeticError) bad argument in arithmetic expression
です。