带变量:
iex(2)> x = %{a: 1, b: 2}
%{a: 1, b: 2}
iex(3)> %{a: 1, b: 2} = y
** (CompileError) iex:3: undefined function y/0
带函数参数变量:
defmodule A do
def go1(z = %{a: a}) do
IO.inspect z
IO.puts a
end
def go2(%{a: a} = z) do
IO.inspect z
IO.puts a
end
end
在 iex 中:
iex(4)> c "a.ex"
warning: redefining module A (current version defined in memory)
a.ex:1
[A]
iex(5)> map = %{a: 1, b: 2}
%{a: 1, b: 2}
iex(6)> A.go1(map)
%{a: 1, b: 2}
1
:ok
iex(7)> A.go2(map)
%{a: 1, b: 2}
1
:ok
函数参数与函数参数变量模式匹配。而且,在 elixir 函数中,参数可以是常量,例如1 或一个原子、映射、元组等——不仅仅是一个变量,如 x、y 或 z。以下是go1() 的工作原理:
A.go1(%{a: 1 b: 2})
|-----+----|
|
| %{a: a} = %{a: 1 b: 2}
V
def go1(z = %{a: a}) do
“参数变量”是%{a: a},它与函数参数%{a: 1 b: 2}相匹配,将a绑定到1。然后,你可能认为你得到了模式匹配:z = %{a: 1},然而,模式匹配%{a: a} = %{a: 1 b: 2}实际上返回了右手边:
iex(10)> %{a: a} = %{a: 1, b: 2}
%{a: 1, b: 2}
因此,您会得到模式匹配:z = %{a: 1, b: 2}。这是另一个演示:
iex(13)> z = %{a: a} = %{a: 1, b: 2}
%{a: 1, b: 2}
iex(14)> a
1
iex(15)> z
%{a: 1, b: 2}
go2() 的工作原理如下:
A.go1(%{a: 1 b: 2})
|-----+----|
|
| z = %{a: 1, b: 2}
V
def go2(%{a: a} = z)
z 是参数变量,它与函数参数%{a: 1 b: 2} 匹配。匹配 z = %{a: 1 b: 2} 返回右侧:
iex(10)> z = %{a: 1, b: 2}
%{a: 1, b: 2}
所以,接下来你会得到模式匹配:%{a: a} = %{a: 1, b: 2},它将a 绑定到1。
因此,一切都是一致的:对于每个模式匹配,包含变量的模式在= 的左侧,而值在右侧。如果您正在寻找一个规则,那就是:在函数定义的参数列表中,= 符号右侧的内容是“参数变量”。左边的东西是在“参数变量”与函数参数匹配后将匹配的模式(或者正如您在其他语言中所说:“在函数参数分配给参数变量之后”)。