我正在阅读Scala编程,第2版(精彩的书,比斯卡拉的网站更好地以非摇滚科学的方式解释事物)并且我注意到这...在回到不可变和可变的时候很奇怪集 .
它将以下内容声明为不可变集
var jetSet=Set("Boeing", "Airbus")
jetSet+="Lear"
println(jetSet.contains("Cessna"))
然后声明只有Mutable集定义了=方法 . 好吧,这很有道理 . 问题是这段代码有效 . 在REPL中测试时创建的集合类型实际上是不可变集合,但它上面定义了=方法,并且它的功能非常好 . 看哪
scala> var a = Set("Adam", "Bill")
a: scala.collection.immutable.Set[String] = Set(Adam, Bill)
scala> a += "Colleen"
scala> println(a)
Set(Adam, Bill, Colleen)
scala> a.getClass
res8: Class[_ <: scala.collection.immutable.Set[String]] = class scala.collection.immutable.Set$Set3
但是如果我声明Set为val,则创建不可变集 does not have the += method defined
scala> val b = Set("Adam", "Bill")
b: scala.collection.immutable.Set[String] = Set(Adam, Bill)
scala> b += "Colleen"
<console>:9: error: value += is not a member of scala.collection.immutable.Set[String]
b += "Colleen"
这里发生了什么?它们都被声明为一个不可变的Set,但声明var可以访问=方法并且可以使用它 .
另外,当我继续在var Immutable Set上调用getClass方法时,我发现了一些奇怪的东西....
scala> a.getClass
res10: Class[_ <: scala.collection.immutable.Set[String]] = class scala.collection.immutable.Set$Set3
scala> a += "One"
scala> a.getClass
res12: Class[_ <: scala.collection.immutable.Set[String]] = class scala.collection.immutable.Set$Set4
scala> a += "Two"
scala> a.getClass
res14: Class[_ <: scala.collection.immutable.Set[String]] = class scala.collection.immutable.HashSet$HashTrieSet
scala> a += "Tree"
scala> a.getClass
res16: Class[_ <: scala.collection.immutable.Set[String]] = class scala.collection.immutable.HashSet$HashTrieSet
scala> a
res17: scala.collection.immutable.Set[String] = Set(One, Tree, Bill, Adam, Two, Colleen)
我的猜测是,由于一些隐藏的语法糖,Scala认识到它是一个Var并且允许你用新构造的集合替换它 .
1 回答
什么是可变的不是
Set
,是对它的引用 .返回一个新的不可变集,分配给可变变量
a
Scala执行语法转换,将表达式转换为
如果
+=
未定义(如不可变的Set
)显然
+=
在a
是val
时没有意义,因为你无法重新分配它,因此被禁止 .以下是Scala编程中的摘录(第17.3节)
如果您继续阅读该部分,您将通过示例找到更全面的解释 .