Scala 构造函数参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18623687/
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
Scala Constructor Parameters
提问by user2456976
What is the difference between a private var constructor parameter and a constructor parameter without val/var? Are they same in terms of scope/visibility?
私有 var 构造函数参数和没有 val/var 的构造函数参数有什么区别?它们在范围/可见性方面是否相同?
Ex:
前任:
class Person(private var firstName:String, lastName:String)
回答by Travis Brown
Yes, there are two important differences. First for the easy one: constructor parameters without the varor valkeywords are not mutable variables—their values can't be changed in the body of the class.
是的,有两个重要的区别。首先是简单的:没有varorval关键字的构造函数参数不是可变变量——它们的值不能在类的主体中改变。
Even if we restrict ourselves to the valkeyword, though, there's still a difference between private valand keyword-less parameters. Consider the following:
即使我们将自己限制在val关键字上,但无private val关键字参数之间仍然存在差异。考虑以下:
class Person(private val firstName: String, lastName: String)
If we look at the compiled class with javap -v Person, we'll see that it only has one field, for firstName. lastNameis just a constructor parameter, which means it may be garbage-collected after the class is initialized, etc.
如果我们查看带有 的编译后的类javap -v Person,我们会看到它只有一个字段 for firstName。lastName只是一个构造函数参数,这意味着它可能在类初始化后被垃圾收集等。
The compiler is smart enough to know when the value of lastNamewill be needed after initialization, and it will create a field for it in that case. Consider the following variation:
编译器足够聪明,可以知道lastName初始化后何时需要的值,并且在这种情况下会为其创建一个字段。考虑以下变体:
class Person(private val firstName: String, lastName: String) {
def fullName = firstName + " " + lastName
}
The compiler can tell that it may need the value of lastNamelater, and if we check javapagain we'll see that the class has two fields (note that if we'd defined fullNameas a valinstead of a def, it'd only have one field).
编译器可以告诉它可能需要lastName稍后的值,如果我们javap再次检查,我们会看到该类有两个字段(注意,如果我们定义fullName为 aval而不是 a def,则它只有一个字段) .
Lastly, note that if we make firstNameobject-privateinstead of class-private, it works exactly like a plain old keyword-less constructor parameter:
最后,请注意,如果我们使用firstNameobject-private而不是class-private,它的工作方式与普通的无关键字构造函数参数完全一样:
class Person(private[this] val firstName: String, lastName: String)
This works even with varinstead of val:
这甚至适用于var而不是val:
class Person(private[this] var firstName: String, lastName: String)
Both of these classes will have no fields. See section 5.2 of the language specificationfor more details about object-private access.
这两个类都没有字段。有关对象私有访问的更多详细信息,请参阅语言规范的第 5.2 节。
回答by Ambling
as a supplement, if your class is a case class, all of the constructor parameters will be automatically public fields.
作为补充,如果您的类是案例类,则所有构造函数参数将自动为公共字段。
The compiler will complain about the private keyword if it exists, and for the parameters without val/var, no matter they are used or not in any defs, there will be public fields generated for them.
如果private关键字存在编译器会报错,对于没有val/var的参数,无论在任何defs中使用与否,都会为它们生成public字段。

