Я занимаюсь программированием в Scala, 2nd Edition (фантастическая книга, намного лучше, чем сайт scala для объяснения вещей в не-ракетно-научном стиле) и Я заметил эту ... странность при переходе на Неизменяемые и Mutable Sets.Scala Immutable Set является Mutable при объявлении как var
Он заявляет следующее в качестве неизменного набора
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
Но если я объявляю набор быть вал, Неизменное набор созданных не имеют + = метод определен
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"
Что здесь происходит? Оба они утверждаются как неизменяемый набор, но тот, который объявлен var, имеет доступ к методу + = и может использовать его.
Кроме того, когда я звала метод GetClass на вар непреложных Set я заметил что-то странное ....
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 и в любом случае, вы можете заменить его новым конструированным множеством.
«Set» неизменен, но 'a' изменен, добавление элемента в набор создает новый набор, а результат присваивается' a', если 'a' является val, он неизменен, и вы не может переназначить его. –