'val' или 'var', изменчивый или неизменный?

Я могу определить переменную (по var) это неизменно:

var x = scala.collection.immutable.Set("aaaaaa","bbbbbb")
println(x.isInstanceOf[scala.collection.immutable.Set[String]])
x += "cccc"
println(x.isInstanceOf[scala.collection.immutable.Set[String]])

Это приводит к:

true
true

+= метод не является членом scala.collection.immutable.Setтак что происходит?

2 ответа

Решение

Компилятор ищет x.+= ...и, если он не может его найти, он пытается преобразовать выражение в x = x + ... (который только успешно, если x это var, или же x Desugars в вызов некоторых update метод). поскольку immutable.Set реализует + оператор и x это varэто удается.

Оригинальный неизменный набор все еще остается неизменным.

Продолжая ответ Кена, + создал новый набор, добавил новый элемент и возвратил новый набор, оставив исходный объект набора без изменений. Так что можно сказать var y = x; y += "cccc" и у вас будет 2 комплекта вместо 1:

var x = scala.collection.immutable.Set("aaaaaa","bbbbbb")
println(x.isInstanceOf[scala.collection.immutable.Set[String]])
var y = x
y += "cccc"
println(x)
println(y)
println(x.isInstanceOf[scala.collection.immutable.Set[String]])
println(y.isInstanceOf[scala.collection.immutable.Set[String]])

Получение:

> true
> Set(aaaaaa, bbbbbb)
> Set(aaaaaa, bbbbbb, cccc)
> true
> true

Вы видите, что сама структура данных остается неизменной, но потому что вы объявили var, назначение является изменчивым. Таким образом, он может быть переназначен на новый объект, если он возвращается. Если вы измените объявление x как val, то вы не можете переназначить его на новый адрес.

Если вы использовали изменяемый набор, то x а также y будет указывать на тот же объект, потому что + call добавил бы существующий набор, а не возвращал новый (будучи изменяемым...):

var x = scala.collection.mutable.Set("aaaaaa","bbbbbb")
println(x.isInstanceOf[scala.collection.immutable.Set[String]])
var y = x
y += "cccc"
println(x)
println(y)

Получить:

> Set("aaaaaa","bbbbbb","cccc")
> Set("aaaaaa","bbbbbb","cccc")

Вуаля.

Другие вопросы по тегам