control flowの章の、 [Elixir in Action]Erlang/Elixirの再帰計算におけるnon-tail recursionとtail recursion 以外のことを。
以下のように、文字列バイナリも左辺/右辺のマッチングによって分けることができます。
iex > a = "hello world" iex > "hello " <> b = a iex > b "world"
以下のように、連続したマッチングもできます。
iex(5)> a = ( b = 1 + 2 ) 3 iex(6)> b 3
以下のように書いた場合、パターンマッチングでは上から順にマッチングを試みます。そのため a(other) が最も先頭にきたらそれがマッチングされます。
defmodule Sample do
def a({:sample1, b}), do: something
def a({:sample2, c}), do: something
def a(other), do: something
end
Elixirでは、以下のようなGuard clauseによっても適用される関数を条件付けすることができます。この時、 when で使われる型には優先度が存在します。
defmodule Sample do def a(x) when x < 0, do: something def a(0), do: something def a(x) when x > 0, do: something end
優先度は以下。
number < atom < reference < fun < port < pid < tuple < map < list < bitstring(binary)
つまり、上記の Sample.a/1 に対してatomの :not_a_number を適用した場合、
def a(x) when x > 0, do: something
が適用されます。エラーはありません。
そのため、数字だけを受け付けるようにするために以下のように書きます。
defmodule Sample do def a(x) when is_number and x < 0, do: something def a(0), do: something def a(x) when is_number and x > 0, do: something end
これで、 :not_a_number のようなものは FunctionClauseError がraiseされるようになります。
Cmprehensionsは、 for x <- [list], do: {何か} で構成される。 into などの要素を使ったりすると、繰り返しをより簡潔にかけたりする。なるほど。
Streamの説明もありましたが、Stream、色々できそうですね。
File.stream! でStreamにした後にごにょごにょStreamで操作した最後にto_list などでlistにして処理をする、といった例が載ってましたが、イマドキぽい感じがします 🙂
1 Comment