Scala集合中的可变与不可变

46

我是Scala的新手,正在努力理解集合层次结构。我看到有“可变”和“不可变”集合之分,但我不明白在实现级别上这实际上意味着什么,以及它与valvar有何关系。能否有人给我一些见解?此外,每个集合类都有“可变”版本和“不可变”版本,还是有些类只能是“可变”或“不可变”的?

2个回答

65

可变表示您可以在原地更改集合。因此,如果您有一个集合 c 并使用 += 添加元素,则 c 已更改,引用该集合的每个其他位置也是如此。

不可变表示集合对象永远不会更改;相反,您可以通过诸如 +++ 的操作构建新的集合对象,这些操作返回一个新的集合。这在并发算法中非常有用,因为它不需要锁定来向集合添加内容。它可能会带来一些额外开销,但这种属性非常有用。Scala 的不可变集合是完全持久化数据结构

区别非常类似于 varval 之间的区别,但要注意:

  1. 您可以就地修改绑定到val的可变集合,尽管您无法重新分配val
  2. 您无法就地修改不可变集合,但如果它分配给var,则可以通过 +等操作将该var 重新分配为由其构建的集合。

并非所有集合都一定存在可变和不可变的变种;上次我检查时,只有可变优先级队列得到了支持。


var a = 0 中,如果两个线程同时尝试并发执行 a = 1a = 2,那么它是如何处理的?这不需要锁定吗? - Jus12

6

Immutable意味着不可改变的。 val使得引用不可改变,这意味着一旦它被初始化,就不能给val赋值。不可变集合使得集合本身不可改变而不是对其的引用。每次修改不可变集合时,都会产生另一个集合,而不是直接在原始集合中进行修改。大多数集合都有不可变和可变版本,但当然也有例外。


“每次修改不可变集合时,都会生成另一个集合,而不是直接在原始集合上进行修改。” - 这是真的吗?实际上,难道不是程序员的责任深度克隆对象并对其进行修改吗?我认为当我们尝试修改不可变集合时,它会报错。 - Dravidian
没有深度克隆。引用被“复制”,而不是对象。 - agilesteel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接