Scala 构造函数参数 [英] Scala Constructor Parameters
问题描述
私有 var 构造函数参数和没有 val/var 的构造函数参数有什么区别?它们在范围/可见性方面是否相同?
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?
例如:
class Person(private var firstName:String, lastName:String)
推荐答案
是的,有两个重要的区别.首先是简单的:没有 var
或 val
关键字的构造函数参数不是可变变量——它们的值不能在类的主体中改变.
Yes, there are two important differences. First for the easy one: constructor parameters without the var
or val
keywords are not mutable variables—their values can't be changed in the body of the class.
即使我们将自己限制为 val
关键字,private val
和无关键字参数之间仍然存在差异.考虑以下几点:
Even if we restrict ourselves to the val
keyword, though, there's still a difference between private val
and keyword-less parameters. Consider the following:
class Person(private val firstName: String, lastName: String)
如果我们使用 javap -v Person
查看编译后的类,我们会看到它只有一个字段,用于 firstName
.lastName
只是一个构造函数参数,这意味着它可能会在类初始化等之后被垃圾收集.
If we look at the compiled class with javap -v Person
, we'll see that it only has one field, for firstName
. lastName
is just a constructor parameter, which means it may be garbage-collected after the class is initialized, etc.
编译器足够聪明,知道初始化后何时需要 lastName
的值,并且在这种情况下会为其创建一个字段.考虑以下变体:
The compiler is smart enough to know when the value of lastName
will be needed after initialization, and it will create a field for it in that case. Consider the following variation:
class Person(private val firstName: String, lastName: String) {
def fullName = firstName + " " + lastName
}
编译器可以告诉它稍后可能需要lastName
的值,如果我们再次检查javap
,我们会看到该类有两个字段(注意如果我们将 fullName
定义为 val
而不是 def
,它只会有一个字段).
The compiler can tell that it may need the value of lastName
later, and if we check javap
again we'll see that the class has two fields (note that if we'd defined fullName
as a val
instead of a def
, it'd only have one field).
最后,请注意,如果我们使用 firstName
object-private 而不是 class-private,它的工作方式与普通的旧关键字完全相同-更少的构造函数参数:
Lastly, note that if we make firstName
object-private instead of class-private, it works exactly like a plain old keyword-less constructor parameter:
class Person(private[this] val firstName: String, lastName: String)
这甚至适用于 var
而不是 val
:
This works even with var
instead of val
:
class Person(private[this] var firstName: String, lastName: String)
这两个类都没有字段.有关更多详细信息,请参阅语言规范的第 5.2 节关于对象私有访问.
Both of these classes will have no fields. See section 5.2 of the language specification for more details about object-private access.
这篇关于Scala 构造函数参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!