添加到不可变的哈希集



对不起,伙计们,我最近在"Scala编程"中看到了一个例子,第2版第685页,这对我来说似乎很奇怪:

var hashSet: Set[C] = new collection.immutable.HashSet
hashSet += elem1

如何添加不可变集合的内容?我尝试了 REPL,它工作正常!

> scala
Welcome to Scala version 2.11.6 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_11).
Type in expressions to have them evaluated.
Type :help for more information.
scala> var s : Set[Int] = collection.immutable.HashSet()
s: Set[Int] = Set()
scala> s += 1324
scala> println(s)
Set(1324)

更奇怪的事实是 += 运算符不是在不可变中定义的。哈希集 API 页面。有人可以帮我了解发生了什么吗?

谢谢。

您没有添加到HashSet 中。您正在分配给hashSet,这完全没问题,因为hashSetvar,而不是val

第 6.12.4 节 Scala 语言规范 (SLS) 的赋值运算符解释了这些复合赋值运算符是如何脱糖的:

l ω= r

(其中ω是除<>!以外的任何运算符字符序列,并且不以=开头)脱糖为

l.ω=(r)

iff l具有或可隐式转换为具有名为 ω= 的成员的对象。

否则,它会被脱糖到

l = l.ω(r)

(除非l保证只评估一次),如果该类型检查。

这允许像+=这样的东西像在其他语言中一样工作,但仍然被覆盖以执行不同的事情。

观察这个:

scala> var hashSet: Set[Int] = new collection.immutable.HashSet
hashSet: Set[Int] = Set()
scala> val set2 = hashSet + 1234
set2: scala.collection.immutable.Set[Int] = Set(1234)
scala> set2
res20: scala.collection.immutable.Set[Int] = Set(1234)
scala> hashSet
res21: Set[Int] = Set()

因此,没有任何东西被添加到不可变的hashSet中。 hashSet与建造时相同。 + 完全返回一个新集合,并且原始集合保持不变。

当你做hashSet += 1234时,它是一个scala的简写(注意HashSet中不存在+=方法):

val temp = hashSet + 1234
hashSet = temp

+=将适用于遵循此协议的任何类。简而言之,当你做a += 12. a必须有一个方法+该方法返回与a相同的类型,并且a应该是可分配的(即var。它不适用于瓦尔。试试这个:val i = 23; i+=1)。

简答

您有一个var,因此可以重新分配给它。所以在这种情况下+=将被翻译成

hashSet = hashSet + elem

就像其他类型一样,只要在它们上定义了+

var i = 0
i += 1
i = i + 1

immutable.HashSeth+方法

创建具有附加元素的新集,除非该元素是 已经存在。

根据文档。

此类中没有定义+=方法,因此+=编译器将提供给您的一种合成方法,它充当运算符,只需通过传递右操作数并将结果赋回左操作数来调用左操作数上的 + 方法。

最新更新