【问题标题】:Accessibility of primary constructor parameters in scalascala中主要构造函数参数的可访问性
【发布时间】:2014-01-22 16:58:16
【问题描述】:

我很难理解主构造函数及其参数的概念。到目前为止我的理解是:如果我们定义一个类如下

class Example(a: Int, b: Int)

Scala 编译器使用上述两个参数生成类示例的主构造函数。但是,它没有在类 Example 的定义中定义字段 ab。但是如果我们定义

class Example(val a: Int, val b: Int)

scala 编译器如上生成主构造函数,并在类定义中添加两个字段。

现在问题来了,当我尝试像这样的例子时

class PrimaryConstructor(a: Int, b: Int){
    override def toString() = "PrimaryConstructor(" + this.a + ", " + this.b + ")"
}

即使没有名为 ab 的字段,上述代码也能很好地编译。我无法理解,如果没有任何字段,那么我如何能够使用 this 访问它们:当前对象引用。

object Main{
    def main(args: Array[String]){
            val primaryConstructor = new PrimaryConstructor(1, 2)
            println(primaryConstructor.a)
    }
}

如果我尝试从上面的类定义外部访问它们,编译后会收到以下错误消息。

error: value a is not a member of PrimaryConstructor
    println(primaryConstructor.a)

我可以理解这一点。但是,如何使用 this 访问这些字段?请帮助我理解这一点。

【问题讨论】:

  • 如果您有一些 Javascript 经验,请尝试放弃 Java 类的概念,而将类视为主构造函数中参数的闭包(函数)。 “一切都作为闭包”的概念是 scala 的核心概念,一旦你理解它就会非常强大。主构造函数确保有一个单一的规范的状态表示,一个类与行为相关联。

标签: scala constructor


【解决方案1】:

它基本上是生成一个私有的val,所以

class A(a:Int) {
    def func = a
}

class A(private[this] val a:Int) {
    def func = a
}

是等价的。如果您省略该函数,这可能并不完全正确。

当在构造函数体之外引用构造函数参数时(例如上面的示例func),Scala 会生成private[this] val,否则不会。

您可以查看 scala 规范以获取更多详细信息或查看this stackoverflow question

【讨论】:

  • 非常感谢。我试图用'javap -p PrimaryConstructor'反汇编来查看私有字段并显示它们。
【解决方案2】:

马丁的回答很棒:

它基本上是生成一个私有的val,所以

class A(a:Int) {
  def func = a
}

class A(private[this] val a:Int) {
  def func = a
}

是等价的,您可以从班级内部访问a

但是,请注意 class A(a: Int) 表示字段 ainstance 私有的。这意味着你不能写这样的东西:

class A(a: Int){
  def sum(other: A): Int = {
    this.a + other.a
  }
}

other.a 是不允许的,即使两个实例属于同一类型。您只能使用this.a

【讨论】:

    猜你喜欢
    • 2019-10-02
    • 1970-01-01
    • 1970-01-01
    • 2012-05-12
    • 2013-09-08
    • 1970-01-01
    • 2023-04-02
    • 2013-03-16
    • 1970-01-01
    相关资源
    最近更新 更多