简体   繁体   English

Scala构造函数参数

[英]Scala Constructor Parameters

What is the difference between a private var constructor parameter and a constructor parameter without val/var? 私有var构造函数参数和没有val / var的构造函数参数之间有什么区别? Are they same in terms of scope/visibility? 它们的范围/可见度是否相同?

Ex: 例如:

class Person(private var firstName:String, lastName:String)

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. 首先是简单的:没有varval关键字的构造函数参数不是可变变量 - 它们的值不能在类的主体中更改。

Even if we restrict ourselves to the val keyword, though, there's still a difference between private val and keyword-less parameters. 即使我们将自己局限于val关键字, private val和无关键字参数之间仍然存在差异。 Consider the following: 考虑以下:

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 . 如果我们用javap -v Person查看编译的类,我们会看到它只有一个字段,对于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. 编译器足够聪明,可以知道初始化后何时需要lastName的值,并且在这种情况下它将为它创建一个字段。 Consider the following variation: 请考虑以下变体:

class Person(private val firstName: String, lastName: String) {
  def fullName = firstName + " " + lastName
}

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). 编译器可以告诉它以后可能需要lastName的值,如果我们再次检查javap ,我们会看到该类有两个字段(请注意,如果我们将fullName定义为val而不是def ,那么它就是只有一个字段)。

Lastly, note that if we make firstName object-private instead of class-private , it works exactly like a plain old keyword-less constructor parameter: 最后,请注意,如果我们使firstName object-private而不是class-private ,它的工作方式与普通的无关键字构造函数参数完全相同:

class Person(private[this] val firstName: String, lastName: String)

This works even with var instead 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 specification for more details about object-private access. 有关对象 - 私有访问的更多详细信息,请参阅语言规范的第5.2节。

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中使用它们,都会为它们生成公共字段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM