Does val or var make difference in immutable objects like lists or tuple?
scala> val ab = List(1,2,3)
ab: List[Int] = List(1, 2, 3)
scala> var ab = List(1,2,3)
ab: List[Int] = List(1, 2, 3)
I am beginner in scala.
Does val or var make difference in immutable objects like lists or tuple?
scala> val ab = List(1,2,3)
ab: List[Int] = List(1, 2, 3)
scala> var ab = List(1,2,3)
ab: List[Int] = List(1, 2, 3)
I am beginner in scala.
You may be confusing two different aspects of immutability. The local variable ab
refers to some object in memory, in this case a List
. When you declare ab
as a val
you are instructing the compiler that ab
will always refer to the same object. Because List
is immutable, its contents will never change, but a var
referring to it might be reassigned to some other List
.
scala> import scala.collection.mutable.MutableList
import scala.collection.mutable.MutableList
scala> val a = List(1,2,3,4)
a: List[Int] = List(1, 2, 3, 4)
scala> val b = MutableList(1,2,3,4)
b: scala.collection.mutable.MutableList[Int] = MutableList(1, 2, 3, 4)
scala> var c = List(1,2,3,4)
c: List[Int] = List(1, 2, 3, 4)
Here, a
is a val
containing an immutable data structure. a
refers to List(1,2,3,4)
and will always do so.
The val b
refers to a MutableList
. We can change the internal contents of the MutableList
but we cannot assign b
to a different MutableList
.
scala> b += 5
res6: b.type = MutableList(1, 2, 3, 4, 5)
scala> b = MutableList(2,3,5,7)
<console>:12: error: reassignment to val
b = MutableList(2,3,5,7)
^
With var c
we have a variable that refers to an immutable data structure List
but that can be reassigned to a different List
.
scala> c = c :+ 5
c: List[Int] = List(1, 2, 3, 4, 5)
Note that the :+
operator (unlike the +=
operator above) does not change the List
referred to by c
. Instead it create a copy of the List
with the element 5
appended. Because c
was declared a var
we can then assign this new list to c
.
It's not really relevant whether the object that ab
points to is mutable. val
means that you cannot in the future assign ab to another value, while var
allows it.
Try repeating the assignment in each case and see what happens:
scala> val ab = List(1,2,3)
ab: List[Int] = List(1, 2, 3)
scala> ab = List(1,2,3)
reassignment to val; not found: value ab
scala> var ab = List(1,2,3)
ab: List[Int] = List(1, 2, 3)
scala> ab = List(1,2,3)
ab: List[Int] = List(1, 2, 3)
It's a question of style.
In Scala using a val
is generally preferred to using a var
as in (functional) programming immutability makes it easier to reason about a program.
So if you can get what you want without resorting to var it is the way to go.
A typical application of a var would be if you want to use an immutable data structure and update it benifitting of structural sharing.
var data = List.empty[String] // var is importan here
def addToData(s: String) : Unit = { data = s :: data }
The same could be achieved by using a mutable datastructure
import scala.collection.mutable.ArrayBuffer
val data = ArrayBuffer.empty[String]
data += "Hello" // this function is here from the beginning
For an in depth discussion look at https://stackoverflow.com/a/4440614/344116 .