1

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.

WoodChopper
  • 4,265
  • 6
  • 31
  • 55
  • A `var` can reference new/different mutable or immutable objects at different times in the program. A `val` cannot. – jwvh Sep 27 '15 at 06:56
  • possible duplicate of [What is the difference between a var and val definition in Scala?](http://stackoverflow.com/questions/1791408/what-is-the-difference-between-a-var-and-val-definition-in-scala) – Kevin Meredith Sep 27 '15 at 15:33

3 Answers3

3

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.

BL16
  • 46
  • 3
2

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)
Yosef Weiner
  • 5,432
  • 1
  • 24
  • 37
-2

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 .

Community
  • 1
  • 1
Andreas Neumann
  • 10,734
  • 1
  • 32
  • 52