带变量:
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
In 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()
works:
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
to 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()
works:
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
to 1
.
因此,一切都是一致的:对于每个模式匹配,包含变量的模式位于=
,值位于右侧。如果你正在寻找一条规则,那就是:在函数定义的参数列表中,右边的东西=
符号是“参数变量”。左边的东西是一个模式,在“参数变量”与函数参数匹配之后(或者正如您在其他语言中所说的:“在函数参数分配给参数变量之后”),它将被匹配。