Просто объявляя что-то как val
вместо var
в Scala не делает его неизменным. Фактически, var
может назвать неизменяемое значение. Следует помнить, что переменные в Scala, как и переменные в Java, всегда * references или обрабатывают, а не фактически содержат значение.
Попробуйте это в РЕПЛ:
class Container { var content: String = "default" }
val a = new Container
val b = a
b.content = "modified"
println(a.content)
При запуске val b = a
вы делаете b
и a
имена для одного и того же (не копия, точно такой же экземпляр контейнера). Из-за этого при запуске b.content = "modified"
изменение отражается в a
; это просто другое имя для того же самого. Обратите внимание, что это происходит, хотя a
- это val. Все значение val
означает, что вы не можете изменить какой экземпляр a
- это имя.
Теперь подумайте об этом небольшом изменении:
class Container { var content: String = "default" }
def update(c: Container) { c.content = "modified" }
val a = new Container
update(a)
println(a.content)
При вызове update
, его параметр c
является также ссылкой или псевдоним a
. Таким образом, изменения отражаются вне вызова метода так же, как и в предыдущем примере.
Массивы изменяемы, поэтому они работают так же.
*: Примитивные переменные (байты, двойники, int и т. Д.) Не являются ссылками в Java; их эквиваленты в штучной упаковке (java.lang.Byte ...). Это не показывает многого, так как эти классы/типы в любом случае неизменны.
Спасибо, все. Я считал массив неизменным, чего не должно быть. Забавно, что я никогда не сталкивался с этим до сих пор (большая часть моего кода - чистая Scala, а затем вы используете разные шаблоны - по крайней мере, я :-) – Maarten