Scala中的Mutable Set + =返回值

时间:2018-08-24 19:20:09

标签: scala collections set assignment-operator mutability

据我了解,在可变集合上使用+=方法的重点是

val s = collection.mutable.Set(1)
s += 2  // s is now a mutable Set(1, 2)

具有类似于

的效果
var s = Set(1) // immutable
s += 2  // s is now an immutable Set(1, 2)

如果是这样,为什么可变Set上的+=方法返回Set本身?这样不会使代码更难以重构,例如

val s = collection.mutable.Set(1)
val s1 = s += 2  // s and s1 are now mutable Set(1, 2)

无法重构为

var s = Set(1) // immutable
var s1 = s += 2  // s is immutable Set(1, 2), s1 is now ()

同时保持原始含义。做出此设计决定的原因是什么?

2 个答案:

答案 0 :(得分:2)

(这显然只是一个猜测)

可变Scala集合旨在用作不可变集合的Builder。 JVM上有一个非常杰出且非常古老的不可变数据结构:String。相应的构建器(不以任何方式绑定到Scala)已经存在于Java中:它是StringBuilder。如果您研究文档,将会看到数十种重载方法append的版本。每次,它返回StringBuilder本身,这使您可以编写以下内容:

// java code
myBuilder
  .append('h')
  .append('i');

我猜想Scala collection.mutable API只是模仿了Java StringBuilder的行为,但是用稍微短一点的append(...)代替了+=。归根结底,这只是经典builder pattern的实现。

答案 1 :(得分:1)

在不变的情况下,s += 2s = s + 2相同。因此,如果使s += 2评估为s的新值,那么您就必须使每个赋值语句对赋值结果进行评估。其他语言也这样做,但是从历史上看,它会导致错误,例如C代码:

if (x = 0) {
  ...
}

所以我认为不让它返回集合是有道理的。

另一方面,对于可变的情况,+=只是一个方法名称,因此它不进行赋值,也不能以有意义的方式真正负责这种错误。使其返回本身可以实现有时有用的那种构建器模式链接。