对不起,伙计们,我最近在"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
,这完全没问题,因为hashSet
是var
,而不是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
有+
方法
创建具有附加元素的新集,除非该元素是 已经存在。
根据文档。
此类中没有定义+=
方法,因此+=
编译器将提供给您的一种合成方法,它充当运算符,只需通过传递右操作数并将结果赋回左操作数来调用左操作数上的 +
方法。