在 Scala 中,我可以将构造函数编写为:
class Cons[T](head: T, tail: List[T]) {
...
}
或者
class Cons[T](val head: T, val tail: List[T]) {
...
}
有什么不同?
在 Scala 中,我可以将构造函数编写为:
class Cons[T](head: T, tail: List[T]) {
...
}
或者
class Cons[T](val head: T, val tail: List[T]) {
...
}
有什么不同?
指定val
使属性可公开访问。(这是case class
参数的默认行为,不需要val
.)
请参阅语言规范的第 5.3 节。
正如其他人所说,不同之处在于,val
除了总是将构造函数参数视为val
.
另一个更细微的区别是val
会在类中创建一个字段,这意味着对参数值的引用将在对象生命周期内存在。
当您不指定 a 时,默认情况下不会发生这种情况val
,但如果您在构造函数主体之外的类主体中使用构造函数参数,仍然可以。例如,a
在 ctor 主体中使用,因此它不会被提升到下面的对象字段中:
class A(a: Int) {
println(a)
}
在以下示例中,a
成为私有字段:
class A(a: Int) {
def foo = a
}
因为必须在构造后和对象生命周期内才能调用foo
.
即使没有从类的主体中引用参数,也可能隐式发生这种情况的另一个地方是使用特化时:
class Foo[@spec A](v: A) {
var value: A = v
}
查看字节码:
public final A v;
flags: ACC_PUBLIC, ACC_FINAL
Signature: #12 // TA;
public A value;
flags: ACC_PUBLIC
Signature: #12 // TA;
这是使用测试的2.10.1
,它可能是专业化实现中的一个错误。