澄清Scala中的var和val

时间:2014-05-23 00:08:19

标签: scala immutability

我期望使用以下代码编译错误:

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)
  }
}

然而,代码编译,我得到以下输出:

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

发生了什么?

当您将val初始化为可变值(反之亦然)时,是否会立即复制它?它是否适用于任何课程?这是一份很深的副本吗?

2 个答案:

答案 0 :(得分:3)

val是引用类(包括String)和不可变值(在复制时不被共享)的实例的不可变引用,如果是值类型(Int,Char,Double,...)< / p>

var分别是可变引用和可变值

事实上,Java和许多其他语言具有完全相同的语义

答案 1 :(得分:2)

您的示例与C,java,python或任何其他编程语言的行为完全相同。

我认为你真的在询问val / var immutable / mutable的区别。这是一个更清晰的例子:

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"

y =始终将y指向新对象,而不是更改y指向的当前对象。这意味着说y =永远不会改变xz

如果A是不可变的(class A(s: String)),那么唯一的区别是操作x.s =将被禁止。高于此的一切都将完全相同。