Scala 构造函数参数是否默认为私有 val?

我一直在尝试:

class Foo(bar: Int)

Vs:

class Foo(private val bar: Int)

尽管我找不到任何地方说 < code > (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>();
()
}
}
..
35971 次浏览

bar: Int

这几乎不是一个构造函数参数。如果除了构造函数之外,这个变量没有在任何地方使用,那么它就保留在那里。不生成字段。否则将创建 private val bar字段并为其分配 bar参数的值。没有创建 getter。

private val bar: Int

这样的参数声明将创建带有私有 getter 的 private val bar字段。无论参数是否在构造函数旁边使用(例如,在 toString()中或者不在构造函数旁边使用) ,这种行为都是相同的。

val bar: Int

与上面一样,但是类 Scala 的 getter 是公共的

案例类别中的 bar: Int

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

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

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

另一方面,在第二种情况下,bar是一个 正常私有字段,因此这个实例 还有可以访问 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

但事实并非如此:

class Foo(bar: Int) {
def otherBar(f: Foo) {
println(f.bar) // error! cannot access bar of another foo
}
}