我正在閱讀Scala編程第二版(這本書很棒,比scala的網站更好地以非火箭科學的方式解釋事物)以及當我經過不可變和可變集時,我注意到了這個怪事。Scala不可變集在聲明爲變量時是可變的
它聲明以下作爲一個不可變組
var jetSet=Set("Boeing", "Airbus")
jetSet+="Lear"
println(jetSet.contains("Cessna"))
然後指出,只有可變的集定義+ =方法。好吧,這是非常有道理的。問題是這個代碼有效。而在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
但如果我宣佈設定爲VAL,不可改變集創建不具備+ =方法定義
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不可變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)
我的猜測是,由於一些隱藏的語法糖,斯卡拉認識到這是一個變數和無論如何你都可以用新構建的集合替換它。
'Set'是不可變的,但是'a'是可變的,向該集合中添加一個元素將創建一個新集合,並將結果賦給'a',如果'a'是一個val,則它是不可變的,而您不能重新分配給它。 – 2014-10-20 15:31:04