Scala 集合中的可变与不可变
Posted
技术标签:
【中文标题】Scala 集合中的可变与不可变【英文标题】:mutable vs. immutable in Scala collections 【发布时间】:2012-01-07 09:57:55 【问题描述】:我对 Scala 还很陌生,正在尝试了解集合层次结构。我看到“可变”和“不可变”集合之间存在区别,但我不明白这在实现级别的实际含义以及这与val
和var
有何关系。谁能给我一些见解?另外,每个集合类是否都有一个“可变”版本和一个“不可变”版本,或者是否有一些类只能是“可变”或“不可变”?
【问题讨论】:
【参考方案1】:可变意味着您可以就地更改集合。因此,如果您有一个集合 c
,并且您在一个元素后面附加了一个 +=
,那么 c
已更改,对该集合的所有其他引用也已更改。
不可变意味着集合对象永远不会改变;相反,您可以使用+
或++
等操作构建新的集合对象,这些操作返回一个新集合。这在并发算法中很有用,因为它不需要锁定来向集合添加内容。它可能以一些开销为代价,但此属性可能非常有用。 Scala 的不可变集合是fully persistent data structures。
区别与var
和val
之间的区别非常相似,但请注意:
-
您可以就地修改绑定到
val
的可变集合,但不能重新分配val
您无法就地修改不可变集合,但如果将其分配给var
,您可以将该var
重新分配给通过+
等操作构建的集合。
并非所有集合都必然存在于可变和不可变的变体中;我上次检查时,只支持可变优先级队列。
【讨论】:
var a = 0
中,如果两个线程同时尝试同时做a = 1
和a = 2
,它是如何处理的?不需要加锁吗?【参考方案2】:
不可变意味着不可改变。 val
使引用不可更改,这意味着您无法在 val
初始化后为其赋值。不可变集合使集合本身不可更改,而不是对其的引用。每次修改不可变集合时,都会生成另一个集合,而不是就地修改原始集合。大多数集合都有不可变和可变版本,当然也有例外。
【讨论】:
“每次修改不可变集合时,都会生成另一个集合,而不是就地修改原始集合” - 这是真的吗?深度克隆对象并修改它实际上不是程序员的责任吗?我认为当我们尝试修改不可变集合时它会出错。 没有深度克隆。引用被“复制”而不是对象。以上是关于Scala 集合中的可变与不可变的主要内容,如果未能解决你的问题,请参考以下文章