scala 构造函数参数默认为私有 val 吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14694712/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Do scala constructor parameters default to private val?
提问by none
I have been trying:
我已经试了:
class Foo(bar: Int)
vs:
对比:
class Foo(private val bar: Int)
and they seem to behave the same although I couldn't find anywhere saying that (bar:
Int)expands to (private val bar: Int)so my question is, are these
identical/similar?
他们似乎表现得一样,虽然我找不到任何地方说(bar:
Int)扩展到(private val bar: Int)所以我的问题是,这些相同/相似吗?
On a side note, I have been trying to use -Xprint:typeron these code pieces and they
produce the same code except for an extra line in the second one. How do I
read that extra line?
附带说明一下,我一直在尝试使用-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>();
()
}
}
..
回答by Tomasz Nurkiewicz
bar: Int
bar: Int
This is barely a constructor parameter. If this variable is not used anywhere except the constructor, it remains there. No field is generated. Otherwise private val barfield is created and value of barparameter is assigned to it. No getter is created.
这只是一个构造函数参数。如果除了构造函数之外没有在任何地方使用这个变量,它会保留在那里。不生成字段。否则private val bar将创建字段并bar为其分配参数值。没有创建 getter。
private val bar: Int
private val bar: Int
Such declaration of parameter will create private val barfield with private getter. This behavior is the same as above no matter if the parameter was used beside the constructor (e.g. in toString()or not).
这样的参数声明将创建private val bar带有私有 getter 的字段。无论参数是否在构造函数旁边使用(例如 intoString()或 not),此行为都与上述相同。
val bar: Int
val bar: Int
Same as above but Scala-like getter is public
同上,但类 Scala 的 getter 是公开的
bar: Intin case classes
bar: Int以防万一
When case classes are involved, by default each parameter has valmodifier.
当涉及案例类时,默认情况下每个参数都有val修饰符。
回答by gourlaysama
In the first case, baris only a constructor parameter. Since the main constructor is the content of the class itself, it is accessible in it, but only from this very instance. So it is almost equivalent to:
在第一种情况下,bar只是一个构造函数参数。由于主构造函数是类本身的内容,因此可以在其中访问它,但只能从这个实例中访问。所以它几乎相当于:
class Foo(private[this] val bar:Int)
On the other hand, in the second case baris a normalprivate field, so it is accessible to this instance andother instances of Foo.
For example, this compiles fine:
另一方面,在第二种情况下bar是一个普通的私有字段,所以它可以被这个实例和其他实例访问Foo。例如,这编译得很好:
class Foo(private val bar: Int) {
def otherBar(f: Foo) {
println(f.bar) // access bar of another foo
}
}
And runs:
并运行:
scala> val a = new Foo(1)
a: Foo = Foo@7a99d0af
scala> a.otherBar(new Foo(3))
3
But this doesn't:
但这不会:
class Foo(bar: Int) {
def otherBar(f: Foo) {
println(f.bar) // error! cannot access bar of another foo
}
}

