在构造函数中指定val

时间:2013-04-18 21:04:05

标签: scala class-constructors

在Scala中,我可以将构造函数编写为:

class Cons[T](head: T, tail: List[T]) {
...
}

class Cons[T](val head: T, val tail: List[T]) {
...
}

有什么区别?

2 个答案:

答案 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测试的,它可能是专业化实现中的一个错误。