我已经定义了一个Foo
模块:
defmodule Foo do
def hello(x = %{name: name}) do
IO.inspect [x, name]
end
end
如果我运行Foo.hello(%{name: "Alice"})
,我会得到以下结果:
[%{name: "Alice"}, "Alice"]
然后,我了解到我可以重写Foo
模块而不改变它的功能:
defmodule Foo do
def hello(%{name: name} = x) do
IO.inspect [x, name]
end
end
为什么这是可能的?函数参数中的等号是什么?它是普通的匹配算子吗?
根据我的理解,运算符=
将右侧的值与左侧的模式匹配。
[编辑]
在读完贾斯汀的回答后,我自己发了一个答案。但是,我仍然需要帮助。
我想知道=
运算符在函数头中是否表现不同以及原因。
如果有的话,我想找一份官方文件。
答案 0 :(得分:4)
它确实仍然是匹配运营商。
您可以这样做的原因与您可以匹配的原因相同
iex(1)> 1 = x
** (CompileError) iex:3: undefined function x/0
iex(2)> x = 1
1
iex(3)> 1 = x
1
在函数头部内部,x
在您使用函数并将参数传递给它时就会有一个值(同样的原因,您可以将函数定义为def hello(x) do ... end
)。这意味着您可以在匹配运算符的右侧使用它。
答案 1 :(得分:2)
谷歌搜索了一段时间后,我在http://learnyousomeerlang.com/syntax-in-functions找到了解释。
本文引用 Erlang 功能:
valid_time({Date = {Y,M,D}, Time = {H,Min,S}}) ->
io:format("The Date tuple (~p) says today is: ~p/~p/~p,~n",[Date,Y,M,D]),
io:format("The time tuple (~p) indicates: ~p:~p:~p.~n", [Time,H,Min,S]);
然后它说:
请注意,可以在函数头中使用
=
运算符,允许我们匹配元组({Y,M,D}
)内的内容和整个元组({{1} })。
关于 Erlang ,但似乎Elixir上的机制相同。
对于实验,我重新编写了Date
模块,如下所示:
Foo
然后我跑了defmodule Foo do
def hello(%{name: x} = %{name: y}) do
IO.inspect [x, y]
end
end
,得到了这个:
Foo.hello(%{name: "Alice"})
参数上的模式匹配是针对["Alice", "Alice"]
运算符的两个侧的两个模式完成的。