我正在阅读Seven Languages in Seven Weeks以了解不同的编程范例。在关于Scala的章节中,我发现集合是不可变的(至少是来自scala.collection.immutable
的集合)。
但是,有一个例子让我困惑:
scala> val hashMap = HashMap(0->0)
scala> hashMap += 1->1
scala> hashMap
res42: scala.collection.mutable.HashMap[Int,Int] = Map(1 -> 1, 0 -> 0)
但
scala> map = map + 2->2
<console>:9: error: reassignment to val
map = map + 2->2
是+=
重新分配不可变的集合吗?在+=
失败的情况下,val
如何重新分配HashMap
=
?
此外,我尝试了其他集合(List
和Map
),并且“原始”(Int
)和+=
因重新分配错误而失败。 HashMap如何特别?我没有阅读Scala API中的任何特定内容,我找不到+=
运算符的定义(我假设它是一个运算符而不是函数,即使在Scala中,也在C ++或Java中)。登记/>
抱歉这个愚蠢的问题,但由于我是Scala的新手,我自己很难找到资源。
答案 0 :(得分:4)
你是对的,这适用于var
,编译器可以在其中
hashMap += 1->1
并将其去除
hashMap = hashMap + 1->1
但也有另一种可能性。如果您的hashMap
类型为scala.collection.mutable.hashMap
,则会直接调用该类型定义的+=
方法:
hashMap.+=(1->1)
没有重新分配val
,地图只是在内部发生变异。
答案 1 :(得分:3)
hashMap
为collection.mutable.HashMap[Int,Int]
。请注意mutable
包。
许多scala集合都有mutable
个版本。
+=
中有一个名为mutable.HashMap
的方法。
答案 2 :(得分:2)
Scala中有两种类型的集合:Mutable和Immutable
您使用的内容绝对属于可变类别,因此可以重新分配。事实上,如果你试试这个:
val hashMap = scala.collection.immutable.HashMap(0->0)
hashMap += (1->1)
你会得到同样的错误
答案 3 :(得分:2)
与其他一些语言不同,x += y
并不总是在Scala中编译成x = x + y
。 hashMap += 1->1
实际上是一个中缀方法调用(+=
是Scala中的有效方法名称),它在mutable.HashMap类中定义。
你的第一个例子使用了可变的HashMap,你可以在最后一行看到。 Immutable HashMap没有+=
方法。
答案 4 :(得分:1)
请注意,对于可变HashMap
scala> val map = scala.collection.mutable.HashMap[Int,Int](0 -> 0)
map: scala.collection.mutable.HashMap[Int,Int] = Map(0 -> 0)
可以在不使用val
或var
,
scala> map += 1->1
res1: map.type = Map(1 -> 1, 0 -> 0)
scala> map += 2->2
res2: map.type = Map(2 -> 2, 1 -> 1, 0 -> 0)
scala> map
res3: scala.collection.mutable.HashMap[Int,Int] = Map(2 -> 2, 1 -> 1, 0 -> 0)
但是对于使用HashMap
val
scala> val imap = scala.collection.immutable.HashMap[Int,Int](0 -> 0)
imap: scala.collection.immutable.HashMap[Int,Int] = Map(0 -> 0)
我们不能添加新的对,
scala> imap += 1->1
<console>:10: error: value += is not a member of scala.collection.immutable.HashMap[Int,Int]
imap += 1->1
^
但是我们可以从原始版本创建一个新的HashMap
并添加一对新的
scala> val imap2 = imap.updated(1,1)
imap2: scala.collection.immutable.HashMap[Int,Int] = Map(0 -> 0, 1 -> 1)
即便如此,使用HashMap
var
scala> var imap = scala.collection.immutable.HashMap[Int,Int](0 -> 0)
imap: scala.collection.immutable.HashMap[Int,Int] = Map(0 -> 0)
允许更新内容
scala> imap += 1->1
scala> imap
res11: scala.collection.immutable.HashMap[Int,Int] = Map(0 -> 0, 1 -> 1)