Elixir中函数参数中的等号是什么?

时间:2017-01-31 13:29:21

标签: elixir

我已经定义了一个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

为什么这是可能的?函数参数中的等号是什么?它是普通的匹配算子吗?

根据我的理解,运算符=将右侧的值与左侧的模式匹配。

[编辑]

在读完贾斯汀的回答后,我自己发了一个答案。但是,我仍然需要帮助。

我想知道=运算符在函数头中是否表现不同以及原因。

如果有的话,我想找一份官方文件。

2 个答案:

答案 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"] 运算符的两个侧的两个模式完成的。