ITエンジニアのブログ

IT企業でエンジニアやってる人間の日常について

Scala の immutable が何故か変更可能

手元で実行した Scala 2.11.1 のインタプリタで、 immutable の Array, Set などが何故か変更可能になっている。

scala> var s = scala.collection.immutable.Set[Int]()
s: scala.collection.immutable.Set[Int] = Set()
scala> s += 1
scala> s
s: scala.coolection.immutable.Set[Int] = Set(1)
scala> var a: Array[Int] = Array(1,2,3)
a: Array[Int] = Array(1,2,3)
scala> a(0) = 4
scala> a
a: Array[int] = Array(4,2,3)

immutable ならば代入などは使えないはずなのにおかしい。調査します。

2015/03/06 追記
Scala のリファレンスを見ると、 immutable な collection は、値を追加したりなどする演算は定義されているが、新しいインスタンスを作っているだけで古いインスタンスには変更が無い、ということで、 var で定義された変数にはあたかも破壊的変更が行われているように見えるだけで実際は新しいオブジェクトを参照しているだけだという事が分かった。

scala> val s = Set[Int]()
scala> s += 1
Error

+= という演算子が破壊的代入を行っているように見えただけで実際は s = s + 1 の右辺が新しい値を作っていただけのようだ。確かに s = s + 1 という記法ではそれがよくわかる。