Scala构造函数参数

10 浏览
0 Comments

Scala构造函数参数

私有的var构造函数参数和没有val/var的构造函数参数有什么区别?在作用域/可见性方面它们是相同的吗?

例如:

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

0
0 Comments

Scala Constructor Parameters问题的出现原因是如果类是一个case类,所有的构造参数将自动成为公共字段。如果存在private关键字,编译器将会发出警告,对于没有val/var修饰的参数,无论它们是否在任何defs中使用,都会为它们生成公共字段。

解决方法是使用private关键字来限制构造参数的访问权限,以确保它们不会成为公共字段。下面是使用private关键字解决这个问题的示例代码:

class MyClass(private val parameter1: Int, private val parameter2: String) {
  def method(): Unit = {
    // 使用构造参数
    println(parameter1)
    println(parameter2)
  }
}

在上面的示例中,构造参数parameter1和parameter2都被声明为private,这样它们就不会成为公共字段。在method方法中,可以使用这些构造参数。

通过使用private关键字,我们可以控制构造参数的访问权限,避免它们成为公共字段。这样可以提高代码的封装性和安全性。

0
0 Comments

Scala构造函数参数的出现原因是为了在类的实例化过程中传递参数。在Scala中,构造函数参数可以使用关键字var或val声明为可变或不可变变量。如果没有使用这两个关键字声明构造函数参数,则它们是不可变的变量,即它们的值在类的主体中无法更改。

即使我们限制在关键字val上,private val和无关键字参数之间仍然存在差异。考虑以下示例:

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

如果我们使用javap -v Person命令查看编译后的类,我们会发现它只有一个字段,用于存储firstName。lastName只是一个构造函数参数,这意味着在类初始化后它可能会被垃圾回收等。

编译器聪明地知道在初始化后何时需要lastName的值,并在这种情况下为其创建一个字段。考虑以下变体:

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

编译器可以判断出它可能在后续需要lastName的值,如果我们再次检查javap的输出,我们会发现该类有两个字段(请注意,如果我们将fullName定义为val而不是def,则只有一个字段)。

最后,需要注意的是,如果我们将firstName声明为object-private而不是class-private,它的行为就和普通的无关键字构造函数参数一样:

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

这种情况即使使用var而不是val也适用:

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

这两个类都不会有字段。请参阅语言规范的第5.2节,了解有关对象私有访问的更多详细信息。

你是否在说在像def fullName这样的情况下,private val和无关键字参数之间没有区别?

在2.13.2版本中,class Person(private[this] val firstName: String)和class Person(firstName: String)都会生成字段private[this] val firstName: String。

以上是关于Scala构造函数参数出现原因以及解决方法的整理。

0