Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'val' or 'var', mutable or immutable?

Tags:

scala

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?

like image 948
Mohammad Reza Esmaeilzadeh Avatar asked Feb 22 '11 04:02

Mohammad Reza Esmaeilzadeh


People also ask

What is the difference between a Val and a Var?

In short, the difference is that a val simply gives a name to some computed value and is read-only, while a var is a memory cell that you can write to (you can "mutate" it) again and again. It's easiest to think of this in terms of objects.

How to create a mutable variable in Scala?

In Scala we can declare a variable using var and val keywords. var keyword is used to create a mutable (read-write) variable and val keyword is used to create an immutable (read only) variable. Syntax – Creating mutable variable var message = "Foo" Here, message is declared using the keyword var.

What is the difference between valval and Var in Kotlin?

val is a keyword in Kotlin that allows us to define properties as read-only. Because they are read-only, they cannot be modified. var, on the other hand, is a keyword that can be used to declare properties in Kotlin that are mutable. These properties are not read-only (as with val) and they can be modified at will.

Why define Vals?

When a value is defined you can rest peacefully with the knowledge that regardless of any other code that is introduced and tries to access it, the "val" will retain its value. By extension, reading and debugging code becomes easier when a "val" assigned at the beginning of a code segment is unchanged through the end of the code.


2 Answers

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.

like image 195
Ken Bloom Avatar answered Nov 02 '22 11:11

Ken Bloom


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.

like image 39
Phil H Avatar answered Nov 02 '22 13:11

Phil H