Scala HashMap:不是+ =重新分配到左侧?

时间:2014-02-07 17:40:33

标签: scala immutability

我正在阅读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 =? 此外,我尝试了其他集合(ListMap),并且“原始”(Int)和+=因重新分配错误而失败。 HashMap如何特别?我没有阅读Scala API中的任何特定内容,我找不到+=运算符的定义(我假设它是一个运算符而不是函数,即使在Scala中,也在C ++或Java中)。登记/> 抱歉这个愚蠢的问题,但由于我是Scala的新手,我自己很难找到资源。

5 个答案:

答案 0 :(得分:4)

你是对的,这适用于var,编译器可以在其中

hashMap += 1->1

并将其去除

hashMap = hashMap + 1->1

但也有另一种可能性。如果您的hashMap类型为scala.collection.mutable.hashMap,则会直接调用该类型定义的+=方法:

hashMap.+=(1->1)

没有重新分配val,地图只是在内部发生变异。

答案 1 :(得分:3)

代码示例中的

hashMapcollection.mutable.HashMap[Int,Int]。请注意mutable包。

许多scala集合都有mutable个版本。

+=中有一个名为mutable.HashMap的方法。

答案 2 :(得分:2)

Scala中有两种类型的集合:Mutable和Immutable

  1. Mutable:http://www.scala-lang.org/api/2.10.3/index.html#scala.collection.mutable.package
  2. 不可变:http://www.scala-lang.org/api/2.10.3/index.html#scala.collection.immutable.package
  3. 您使用的内容绝对属于可变类别,因此可以重新分配。事实上,如果你试试这个:

    val hashMap = scala.collection.immutable.HashMap(0->0)
    hashMap += (1->1)
    

    你会得到同样的错误

答案 3 :(得分:2)

与其他一些语言不同,x += y并不总是在Scala中编译成x = x + yhashMap += 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)

可以在不使用valvar

的情况下更改其内容
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)