Emil
Emil

Reputation: 2167

Clarification on var and val in Scala

I was expecting a compiler error with the following code:

object Test {
  def main(args: Array[String]) : Unit = {
    val x = 10
    var y = x
    val z = y

    println("x: " + x)
    println("y: " + y)
    println("z: " + z)

    y = 100

    println("x: " + x)
    println("y: " + y)
    println("z: " + z)
  }
}

However, the code compiles and I get back the following output:

x: 10
y: 10
z: 10
x: 10
y: 100
z: 10

What's going on?

When you initialize a val to a mutable value (or vice-versa), does it immediately copy it? Does it do this for any class? Is it a deep copy?

Upvotes: 0

Views: 90

Answers (2)

dhg
dhg

Reputation: 52701

Your example behaves the exact same way as C, java, python, or any other programming language.

I think you are really asking about the val/var immutable/mutable distinction. Here's a clearer example:

class A(var s: String) {
  override def toString = s
}

val x = new A("first")    // a new A object [Object1] is allocated, x points to it
var y = x                 // y is pointed to x's referent, which is [Object1]
val z = y                 // z is pointed to y's referent, which is [Object1]

println(x)  // "first"
println(y)  // "first"
println(z)  // "first"

y = new A("second")       // a new A object [Object2] is allocated, y points to it

println(x)  // "first"    // note that x is still pointing to the same object [Object1]
println(y)  // "second"
println(z)  // "first"    // so is z

x.s = "third"             // the string *inside* [Object1] is changed

println(x)  // "third"    // x still points to [Object1], which now contains "third"
println(y)  // "second"   // y still points to [Object2]
println(z)  // "third"    // z still points to [Object1], which now contains "third"

Saying y = will always point y at a new object, not change the current object that y points to. This means that saying y = can never change x or z.

If A were immutable (class A(s: String)), then the only difference is that the operation x.s = would be disallowed. Everything above that would be exactly the same.

Upvotes: 2

om-nom-nom
om-nom-nom

Reputation: 62855

val is immutable reference to the instance in case of reference class (including String) and immutable value (which is copied, not shared on assignment), in case of value types (Int, Char, Double, ...)

var is mutable reference and mutable value respectively

In fact Java and many other languages has the very same semantics

Upvotes: 3

Related Questions