サーチ…


ガード句の基本的な使い方

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)を実行するとどうなりますか?システムは最初の実装を見て、 num1あるため、最初の実装のガード節が満たされていることを確認します。その実装を使用して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です。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow