如果Elixir中的变量是不可变的,为什么可以附加到元组和列表?

时间:2018-02-20 00:47:07

标签: elixir

在下面的示例中,我创建了一个列表,然后我在该列表中添加了一个新值。如果Elixir充满了不变性,这怎么可能呢?

l = [1,2,3,4]
  iex> [1,2,3,4]
l = l ++ [5]
  iex> [1,2,3,4,5]

如果我没有弄错,这会将列表重新分配到同一个列表中,这应该是不可能的,当我再次打电话给它时,它应该打印出1到4而不是1到5.我不明白什么?

2 个答案:

答案 0 :(得分:4)

为变量指定新值时,实际上创建一个名称相同的新变量

首先,当你执行l ++ [5]时,l不附加任何内容,因为它是不可变的。相反,会创建包含l新列表和新元素。

现在当你执行l = l ++ [5]时,你并没有真正附加到变量l,你只需删除以前的l变量并创建一个新变量来存储新列表通过将[5]与您之前的l变量相关联来创建。

答案 1 :(得分:1)

可变性与不变性的问题更多地是物理内存的问题。如果我要定义一个列表l并且它位于内存位置1000开始,然后多个线程/进程等都尝试立即追加到列表中我遇到了决定哪些写入实际处理的问题以什么顺序。另一方面,如果每次有人试图修改l我将列表的内容在1000复制到新的内存地址,那么就不必担心锁或互斥或任何类型的机制,因为每个线程/ process等正在获得自己的副本。

注意,这是对实际发生的事情的粗略过度简化,但对于这次讨论,它实际上正在发生的事情。

实际名称并不像每次修改列表时将其复制到新的内存位置那样重要。

因此,如果我有

l = [1, 2, 3, 4]

它开始于内存1000

我跑

l = l ++ [5]

然后丢弃1000处的l并在某个不同的存储位置创建新的l。即使名称相同,它也是两个不同的内存位置。只要它们不共享内存位置,并发就容易得多,因为我不必处理锁或互斥锁或其他机制来处理同时发生的同一物理内存地址的多次写入。