【问题标题】:How do you define a local var/val in the primary constructor in Scala?如何在 Scala 的主构造函数中定义本地 var/val?
【发布时间】:2009-07-13 10:17:59
【问题描述】:

在 Scala 中,类的主要构造函数没有显式的主体,而是从类主体中隐式定义的。那么,如何区分字段和本地值(即构造函数方法的本地值)?

例如,以下面的代码 sn-p 为例,它是“Scala 编程”中一些示例代码的修改形式:

class R(n: Int, d: Int) {
   private val g = myfunc
   val x = n / g
   val y = d / g
}

我的理解是,这将生成一个包含三个字段的类:私有“g”和公共“x”和“y”。但是g值只用于x和y字段的计算,超出构造函数范围没有任何意义。

那么在这个(当然是人为的)示例中,你如何为这个构造函数定义局部值?

【问题讨论】:

  • 发帖以防其他人有与我类似的问题并像我一样先来这里。如果您尝试执行相同的概念,但对于 constructors 使用我的问题的答案:stackoverflow.com/questions/46455835/…

标签: scala scala-primary-constructor


【解决方案1】:

例如

class R(n: Int, d: Int) {
  val (x, y) = {
    val g = myfunc
    (n/g, d/g)
  }
}

【讨论】:

  • 啊,真的很简单。我仍然对功能概念有直觉。
  • 这实际上会在你的类中添加一个隐藏的 Tuple2 字段。
  • 这很重要。谢谢你的评论,豪尔赫。
  • 我不明白这是一个答案。我现在在 2.10.0-RC5 中看到了这个问题。
【解决方案2】:

有几种方法可以做到这一点。您可以在私有定义中声明此类临时变量,以便在构建期间使用。您可以在返回表达式的块内使用临时变量(例如在 Alaz 的答案中)。或者,最后,您可以在备用构造函数中使用此类变量。

以类似于备用构造函数的方式,您也可以在对象伴侣的“应用”方法中定义它们。

不能做的是声明一个字段是“临时的”。

还要注意,主构造函数接收的任何参数也是一个字段。如果您不希望这些参数成为字段,并且不想在构造函数中公开实际字段,通常的解决方案是使用实际字段将主构造函数设为私有,并使用备用构造函数或object-companion 的 apply() 作为有效的“主要”构造函数。

【讨论】:

    【解决方案3】:

    我们的另一个选择是将主对象构造函数设为私有,并使用伴随对象的 apply 方法作为构建器。如果我们将这种方法应用于您的示例(不是双关语),它将如下所示:

    class R private (val x: Int, val y: Int);
    
    object R {
      def apply(n: Int, d: Int): R = {
        val g = myfunc;
        new R(n / g, d / g);
      }
    }
    

    创建一个 R 实例而不是:

    val r = new R(1, 2);
    

    写:

    val r = R(1, 2);
    

    这有点冗长,但我认为可能会更糟:)。让我们希望 private[this] val 在未来的 Scala 版本中被视为临时变量。马丁本人暗示过。

    【讨论】:

    • 从 Scala 2.9.0.RC1 开始,优化尚未实现。
    • robinst,甚至在 Scala 2.10.2 中
    【解决方案4】:

    关于这个话题的一些讨论,包括 Martin Odersky 的 cmets,是here

    【讨论】:

    • 那是书中引发我的问题的确切例子 :) 我想这意味着我正在注意......
    猜你喜欢
    • 2018-03-15
    • 2021-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多