0

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

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

或者

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

有什么不同?

4

2 回答 2

4

指定val使属性可公开访问。(这是case class参数的默认行为,不需要val.)

请参阅语言规范的第 5.3 节。

于 2013-04-18T21:08:07.817 回答
2

正如其他人所说,不同之处在于,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,它可能是专业化实现中的一个错误。

于 2013-04-19T10:56:36.853 回答