斯卡拉不可变Set是可变的吗?

Scala immutable Set is mutable?

The docs say:

A collection in package scala.collection.immutable is guaranteed to be immutable for everyone. Such a collection will never change after it is created.

But I don't get the behavior I would expect from this:

scala> var test3 = scala.collection.immutable.Set[String]("one", "two")
test3: scala.collection.immutable.Set[String] = Set(one, two)

scala> test3 += "three"

scala> println(test3)
Set(one, two, three)

What am I missing here?

There are two things to avoid (if possible) when working with collections. Immutable collections, as you know, are preferred over mutable ones. However, having an immutable collection stored in a mutable variable only "delays" the problem. You moved the mutability along with all the problems it brings from the collection itself to the variable that holds the collection. Either way you have a state.

Ideal solution is to avoid both. That is, to use both immutable collections and immutable fields (vals). For example, a function can be producing an immutable collection and other function can be consuming it, without ever having to keep the collection itself somewhere or modifying it.

OK that's a pretty good rule of thumb to follow, thanks. So basically using var creates a variable that is sort of temporary...when you first assign it, it points to a specific reference in memory (that is immutable), as soon as you add to it, it creates a brand new immutable Set (with the new item) so the variable is pointing to a brand new reference. I can see how that could get you into trouble. OK so I use val almost like I would use the 'final' keyword in Java to ensure that my immutable is always immutable?
Exactly. Using a var means that the variable can change its value, which means that at some point it holds a reference to some immutable collection, but then later on that reference can be pointing to a completely different immutable collection. Just one thing - I wouldn't necessarily call the var "temporary". I mean, it is, but just as much as any normal variable in Java. It's more correct (pardon the stupid term) to say that var is changeable. Its value can be re-assigned, while with vals that's impossible (you pulled a correct parallel to final in Java).

A var can be reassigned (it is a variable, so it can vary). You are then no longer referencing the previous object at all.

A val cannot be reassigned (it is a value, so it cannot vary), but you can call methods on that object, for example if the value is a mutable set.

When I say vary I basically mean that the reference cannot vary. It's a bit confusing, I know.

To put it another way: both vals and vars can point to objects with internal state that itself can change. Like a mutable map.

I encourage you to write a code example yourself that verifies this table:

    | MutableSet                    | ImmutableSet
--------------------------------------------------
var | Reassign. Insert element      | Reassign
val | Insert                        | None of these
That's a handy chart to see at a glance what is going on. Thanks