在Scala中,我可以将构造函数编写为:
class Cons[T](head: T, tail: List[T]) {
...
}
或
class Cons[T](val head: T, val tail: List[T]) {
...
}
有什么区别?
答案 0 :(得分:4)
指定val
可以公开访问该属性。 (这是case class
参数的默认行为,无需val
。)
参见language spec的第5.3节。
答案 1 :(得分:2)
正如其他人所说,不同之处在于val
将公开访问这些值,但案例类除外,它总是将构造函数参数视为val
。
另一个更微妙的区别是val
将在类中创建一个字段,这意味着在对象生存期内对参数值的引用将存在。
当您未指定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
测试的,它可能是专业化实现中的一个错误。