10.6. Understanding Mutable Variables with Immutable Collections
Problem
You may have seen that mixing a mutable variable (var
) with an immutable collection causes
surprising behavior. For instance, when you create an immutable Vector
as a var
, it appears you can somehow add new
elements to it:
scala>var sisters = Vector("Melinda")
sisters: collection.immutable.Vector[String] = Vector(Melinda) scala>sisters = sisters :+ "Melissa"
sisters: collection.immutable.Vector[String] = Vector(Melinda, Melissa) scala>sisters = sisters :+ "Marisa"
sisters: collection.immutable.Vector[String] = Vector(Melinda, Melissa, Marisa) scala>sisters.foreach(println)
Melinda Melissa Marisa
How can this be?
Solution
Though it looks like you’re mutating an immutable collection,
what’s really happening is that the sisters
variable points to a new collection
each time you use the :+
method. The
sisters
variable is mutable—like a
non-final
field in Java—so it’s
actually being reassigned to a new collection during each step. The end
result is similar to these lines of code:
var
sisters
=
Vector
(
"Melinda"
)
sisters
=
Vector
(
"Melinda"
,
"Melissa"
)
sisters
=
Vector
(
"Melinda"
,
"Melissa"
,
"Marisa"
)
In the second and third lines of code, the sisters
reference has been changed to point to
a new collection.
You can demonstrate that the vector itself is immutable. Attempting to mutate one of its elements—which doesn’t involve reassigning the variable—results in an error:
scala> sisters(0) = "Molly"
<console>:12: error: value ...
Get Scala Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.