gpt4 book ai didi

immutability - Elixir 变量真的是不可变的吗?

转载 作者:行者123 更新时间:2023-12-03 05:26:26 29 4
gpt4 key购买 nike

在 Dave Thomas 的《Programming Elixir》一书中,他指出“Elixir 强制执行不可变数据”,并接着说道:

In Elixir, once a variable references a list such as [1,2,3], you know it will always reference those same values (until you rebind the variable).

这听起来像是“除非你改变它,否则它永远不会改变”,所以我对可变性和重新绑定(bind)之间的区别感到困惑。一个突出差异的例子会非常有帮助。

最佳答案

不要将 Elixir 中的“变量”视为命令式语言中的变量、“值的空间”。而是将它们视为“值(value)标签”。

当您了解变量(“标签”)在 Erlang 中的工作原理时,也许您会更好地理解它。每当您将“标签”绑定(bind)到某个值时,它就会永远与其绑定(bind)(范围规则当然适用于此处)。

在 Erlang 中你不能这样写:

v = 1,      % value "1" is now "labelled" "v"
% wherever you write "1", you can write "v" and vice versa
% the "label" and its value are interchangeable

v = v+1, % you can not change the label (rebind it)
v = v*10, % you can not change the label (rebind it)

相反,你必须这样写:

v1 = 1,       % value "1" is now labelled "v1"
v2 = v1+1, % value "2" is now labelled "v2"
v3 = v2*10, % value "20" is now labelled "v3"

正如你所看到的,这非常不方便,主要是为了代码重构。如果您想在第一行之后插入新行,则必须重新编号所有 v* 或编写类似“v1a = ...”的内容

所以在Elixir中你可以重新绑定(bind)变量(改变“标签”的含义),主要是为了你的方便:

v = 1       # value "1" is now labelled "v"
v = v+1 # label "v" is changed: now "2" is labelled "v"
v = v*10 # value "20" is now labelled "v"

摘要:在命令式语言中,变量就像命名的手提箱:您有一个名为“v”的手提箱。首先你把三明治放进去。比你在里面放一个苹果(三明治丢失了,可能被垃圾收集器吃掉了)。在 Erlang 和 Elixir 中,变量不是放置内容的地方。它只是值的名称/标签。在 Elixir 中,您可以更改标签的含义。在 Erlang 中你不能。 这就是为什么在 Erlang 或 Elixir 中“为变量分配内存”没有意义的原因,因为变量不占用空间。值(value)观确实如此。现在也许您清楚地看到了差异。

如果你想深入挖掘:

1) 看看“未绑定(bind)”和“绑定(bind)”变量在 Prolog 中如何工作。这就是 Erlang 中“不变的变量”这个可能有点奇怪的概念的来源。

2) 请注意,Erlang 中的“=”实际上不是一个赋值运算符,它只是一个匹配运算符!当将未绑定(bind)变量与值匹配时,将该变量绑定(bind)到该值。匹配绑定(bind)变量就像匹配它所绑定(bind)的值一样。所以这会产生一个匹配错误:

v = 1,
v = 2, % in fact this is matching: 1 = 2

3) Elixir 中并非如此。所以在 Elixir 中必须有一个特殊的语法来强制匹配:

v = 1
v = 2 # rebinding variable to 2
^v = 3 # matching: 2 = 3 -> error

关于immutability - Elixir 变量真的是不可变的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29967086/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com