Scala 构造函数参数 [英] Scala Constructor Parameters

查看:43
本文介绍了Scala 构造函数参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

私有 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)

推荐答案

是的,有两个重要的区别.首先是简单的:没有 varval 关键字的构造函数参数不是可变变量——它们的值不能在类的主体中改变.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆