2020-05-25 23:47:41
【elixir】caseですでに使用している変数にパターンマッチさせる場合はピン演算子「^」を使う
悩んだときのcase
ピン演算子未使用のときのサンプルです。"nothing"が出力される期待をしていました。
defmodule Casesample do
def main do
a = 3
b = 1
case b do
a -> "pattern match a"
_ -> "nothing"
end
end
end
結果は"pattern match a"が出力されます。
/home/trial # iex casesample.ex
Erlang/OTP 22 [erts-10.7.1] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:1]
warning: variable "a" is unused (if the variable is not meant to be used, prefix it with an underscore)
casesample.ex:8: Casesample.main/0
warning: variable "a" is unused (if the variable is not meant to be used, prefix it with an underscore)
casesample.ex:4: Casesample.main/0
Interactive Elixir (1.9.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> Casesample.main
"pattern match a"
iex(2)>
最初に変数aがunusedと表示されている時点でわかりますが、意図した結果になりません。変数bの値を変数aに束縛させるのでcase内の変数aは変数bの値になります。以下のようにそのまま変数aを返すと結果がわかります。
defmodule Casesample do
def main do
a = 3
b = 1
case b do
a -> a
_ -> "nothing"
end
end
end
iex(2)> r Casesample
warning: redefining module Casesample (current version defined in memory)
casesample.ex:1
warning: variable "a" is unused (if the variable is not meant to be used, prefix it with an underscore)
casesample.ex:4: Casesample.main/0
{:reloaded, Casesample, [Casesample]}
iex(3)> Casesample.main
1
iex(4)>
結果のとおり変数bの値である1が出力されます。
解決するには
ピン演算子を使います。
defmodule Casesample do
def main do
a = 3
b = 1
case b do
^a -> "pattern match a"
_ -> "nothing"
end
end
end
結果は期待通り"nothing"が出力されます。
iex(5)> r Casesample
warning: redefining module Casesample (current version defined in memory)
casesample.ex:1
warning: this check/guard will always yield the same result
casesample.ex:8
{:reloaded, Casesample, [Casesample]}
iex(6)> Casesample.main
"nothing"
iex(7)>
終わり
書籍「プログラミングElixir」の12章にあるcase節には特にこれについて記載はなさそうでした。elixir-langには記載されていました。