Reputation: 1342
I can define a variable (by var
) that is immutable:
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]])
This results in:
true
true
+=
method is not a member of scala.collection.immutable.Set
, so what is happening?
Upvotes: 13
Views: 3176
Reputation: 58770
The compiler looks for x.+= ...
, and if it can't find it, then it tries to transform the statement into x = x + ...
(which only succeeds if x
is a var
, or x
desugars into a call to some update
method). Since immutable.Set
implements a +
operator, and x
is a var
, this succeeds.
Upvotes: 22
Reputation: 20141
The original immutable set is still unchanged.
Continuing Ken's answer, the + has created a new set, appended the new item, and returned the new set, leaving the original set object unchanged. So you could say var y = x; y += "cccc"
and you would have 2 sets instead of 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]])
Getting:
> true
> Set(aaaaaa, bbbbbb)
> Set(aaaaaa, bbbbbb, cccc)
> true
> true
You see the data structure itself is still immutable, but because you declared a var
, the assignment is mutable. So it can be repointed to a new object if that is returned. If you change to declaring x
as a val
, then you couldn't reassign it to a new address.
If you had used a mutable set, then x
and y
would point to the same object because the +
call would have appended the existing set rather than returning a new one (being mutable...):
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)
Get:
> Set("aaaaaa","bbbbbb","cccc")
> Set("aaaaaa","bbbbbb","cccc")
Voila.
Upvotes: 6