iph*_*007 5 functional-programming elixir
我所阅读的有关Elixir的所有内容都表明,应将作业视为模式匹配。如果是这样,那么为什么x = x + 1在Elixir中起作用?对于x = x + 1没有x的值。
我所阅读的有关Elixir的所有内容都表明,应将作业视为模式匹配。
在Elixir中,= 它称为模式匹配运算符,但其工作方式与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>
Run Code Online (Sandbox Code Playgroud)
因此,在Erlang中这将失败:
4> X = X + 1.
** exception error: no match of right hand side value 16
Run Code Online (Sandbox Code Playgroud)
使用Erlang的单次分配,事情很简单:因为X已经有一个值,所以该行X = X + 1不能试图为X赋一个新值,因此该行是试图对match(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)>
Run Code Online (Sandbox Code Playgroud)
变量不是Elixir中的单个赋值,这一事实意味着Elixir在编写时需要做出选择:
x = 10
x = x + 1 #or even x = 15
Run Code Online (Sandbox Code Playgroud)
选择1)第二行应解释为的赋值x吗?
选择2)第二行是否应该解释为尝试模式匹配(即10 = 11)?
Elixir带有Choice1。这意味着用Elixir中的所谓模式匹配运算符实际执行模式匹配更为困难:您必须将pin运算符(^)与match operator(=)结合使用:
x = 10
^x = x + 1
Run Code Online (Sandbox Code Playgroud)
现在,第二行将始终失败。如果您想在不使用pin运算符的情况下执行模式匹配,还有一种技巧在某些情况下会起作用:
x = 10
12 = x
Run Code Online (Sandbox Code Playgroud)
在第二行中,将变量放在右侧。我认为规则可以这样表示:在模式匹配操作符(=)的右侧,总是对变量求值,即用其值替换。始终在左侧分配变量-除非使用pin运算符,否则在这种情况下,固定变量将替换为其当前值,然后在右侧进行模式匹配。结果,将Elixir的=运算符称为混合分配/模式匹配运算符可能更准确。
在模式匹配期间,匹配右侧的值被分配给左侧的匹配变量:
iex(1)> {x, y} = {1, 2}
{1, 2}
iex(2)> x
1
iex(3)> y
2
Run Code Online (Sandbox Code Playgroud)
在右侧,使用匹配之前变量的值。在左侧,设置了变量。
您也可以使用^pin 运算符强制左侧使用变量的值:
iex(4)> x = 1
1
iex(5)> ^x = x + 1
** (MatchError) no match of right hand side value: 2
Run Code Online (Sandbox Code Playgroud)
这将失败,因为它等效于1 = 1 + 1,这是您期望的失败条件。
您可以想象x = x + 1被编译器重写为x2 = x1 + 1。
这非常接近其工作方式。这不是我在这里使用的简单索引号,但是概念是相同的。BEAM看到的变量是不可变的,并且在该级别上没有重新绑定。
在Erlang程序中,您会找到类似的代码X2 = X1 + 1。两种方法都有缺点。JoséValim在设计Elixir时做出了有意识的选择,允许重新绑定变量,并且他写了一篇博客文章,比较了这两种方法以及存在以下风险的各种错误:
http://blog.plataformatec.com.br/2016/01/comparing-elixir-and-erlang-variables/
| 归档时间: |
|
| 查看次数: |
195 次 |
| 最近记录: |