添加到不可变的HashSet

时间:2015-04-27 04:57:48

标签: scala scala-collections immutable-collections

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

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)

更奇怪的是,+ =运算符未在 immutable.HashSet api页面中定义。有人可以帮我理解发生了什么吗?

感谢。

3 个答案:

答案 0 :(得分:4)

您没有添加到HashSet。您分配给hashSet,这非常好,因为hashSetvar,而不是val

Section 6.12.4 Assignment Operators of the Scala Language Specification (SLS)解释了这些复合赋值运算符是如何被去除的:

l ω= r

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

l.ω=(r)

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

否则,它会变得黯然失色

l = l.ω(r)

l除了保证只评估一次),如果那样的话题检查。

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

答案 1 :(得分:3)

观察:

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

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

答案 2 :(得分:2)

简短回答

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

hashSet = hashSet + elem

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

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

详细

immutable.HashSeth+方法

  

使用其他元素创建一个新集合,除非该元素是   已经在场了。

根据docs

此类中没有定义+=方法,因此+=将是一个合成方法given to you by compiler,只需调用+即可充当operator左操作数上的方法,通过传递右操作数并将结果返回给左操作数。