我期望使用以下代码编译错误:
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
初始化为可变值(反之亦然)时,是否会立即复制它?它是否适用于任何课程?这是一份很深的副本吗?
答案 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 =
永远不会改变x
或z
。
如果A
是不可变的(class A(s: String)
),那么唯一的区别是操作x.s =
将被禁止。高于此的一切都将完全相同。