我读到的有关 Elixir 的所有内容都表明,赋值应该被视为模式匹配。
在长生不老药中,=
is称为模式匹配运算符,但它的工作方式与 Erlang 中的模式匹配运算符不同。这是因为在 Elixir 中变量并不像在 Erlang 中那样是单一赋值。这是 Erlang 的工作方式:
~/erlang_programs$ erl
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V9.3 (abort with ^G)
1> X = 15.
15
2> X = 100.
** exception error: no match of right hand side value 100
3> X.
15
4>
因此,在 Erlang 中这会失败:
4> X = X + 1.
** exception error: no match of right hand side value 16
对于 Erlang 的单一赋值,事情非常简单:因为 X 已经有一个值,所以该行X = X + 1
不能尝试为 X 分配新值,因此该行是尝试模式匹配 (15 = 15 + 1
),这总是会失败。
另一方面,在 Elixir 中变量不是单一赋值:
Interactive Elixir (1.6.6) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> x = 15
15
iex(2)> x = 100
100
iex(3)> x
100
iex(4)>
事实上,Elixir 中的变量不是单一赋值,这意味着 Elixir 需要在您编写时做出选择:
x = 10
x = x + 1 #or even x = 15
选择 1) 第二行是否应该被解释为赋值给x
?
选择 2)第二行是否应该被解释为尝试模式匹配(即10 = 11
)?
Elixir 采用选择 1。这意味着在 Elixir 中实际使用所谓的模式匹配运算符执行模式匹配更加困难:您必须使用 pin 运算符(^
) 与匹配运算符(=
):
x = 10
^x = x + 1
现在,第二行总是会失败。如果您想在不使用 pin 运算符的情况下执行模式匹配,还有一个技巧在某些情况下会起作用:
x = 10
12 = x
在第二行中,将变量放在右侧。我认为规则可以这样表述:在模式匹配运算符的右侧(=
),变量总是被评估,即用它们的值替换。左侧的变量总是分配给——除非使用 pin 运算符,在这种情况下,固定变量将被其当前值替换,然后与右侧进行模式匹配。因此,调用 Elixir 可能更准确=
混合赋值/模式匹配运算符。