scala构造函数参数默认为private val吗?

时间:2013-02-04 20:08:37

标签: scala scala-primary-constructor

我一直在努力:

class Foo(bar: Int)

VS

class Foo(private val bar: Int)

他们似乎行为相同,虽然我找不到任何地方说(bar: Int)扩展为(private val bar: Int)所以我的问题是,这些是 相同/相似?

另外,我一直试图在这些代码片段上使用-Xprint:typer 生成相同的代码,除了第二行中的额外行。我如何能 阅读额外的一行?

..
class Foo extends scala.AnyRef {
  <paramaccessor> private[this] val bar: Int = _;
  def <init>(bar: Int): this.Foo = {
    Foo.super.<init>();
    ()
  }
}
..


..
class Foo extends scala.AnyRef {
  <paramaccessor> private[this] val bar: Int = _;
  <stable> <accessor> <paramaccessor> private def bar: Int = Foo.this.bar;
  def <init>(bar: Int): this.Foo = {
    Foo.super.<init>();
    ()
  }
}
..

2 个答案:

答案 0 :(得分:162)

bar: Int

这几乎不是构造函数参数。如果除了构造函数之外没有使用此变量,它仍然存在。没有生成字段。否则,将创建private val bar字段,并为其分配bar参数的值。没有创建getter。

private val bar: Int

这种参数声明将使用私有getter创建private val bar字段。无论参数是否在构造函数旁边使用(例如,在toString()中),此行为与上述相同。

val bar: Int

与上述相同,但类似Scala的getter是公开的

案例类

bar: Int

当涉及案例类时,默认情况下每个参数都有val修饰符。

答案 1 :(得分:85)

在第一种情况下,bar只是一个构造函数参数。由于主构造函数是类本身的内容,因此可以在其中访问它,但仅限于此实例。所以它几乎等同于:

class Foo(private[this] val bar:Int)

另一方面,在第二种情况下,bar普通私有字段,因此该实例可以访问 {{的其他实例1}}。 例如,这编译很好:

Foo

跑步:

class Foo(private val bar: Int) {
  def otherBar(f: Foo) {
    println(f.bar) // access bar of another foo
  }
}

但这不是:

scala> val a = new Foo(1)
a: Foo = Foo@7a99d0af

scala> a.otherBar(new Foo(3))
3