代码之家  ›  专栏  ›  技术社区  ›  skaffman

如何在scala的主构造函数中定义本地var/val?

  •  60
  • skaffman  · 技术社区  · 15 年前

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

    例如,以下面的代码片段为例,这是“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字段,没有超出构造函数范围的意义。

    所以在这个(公认是人工的)例子中,如何定义这个构造函数的局部值呢?

    4 回复  |  直到 10 年前
        1
  •  37
  •   Alexander Azarov    15 年前

    例如。

    class R(n: Int, d: Int) {
      val (x, y) = {
        val g = myfunc
        (n/g, d/g)
      }
    }
    
        2
  •  16
  •   Daniel C. Sobral    15 年前

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

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

    你什么 不能 do是将字段声明为“临时”。

    还要注意,主构造函数接收到的任何参数也是一个字段。如果不希望此类参数成为字段,也不希望在构造函数中公开实际字段,通常的解决方案是将主构造函数与实际字段一起私有化,并使用备用构造函数或对象伙伴的apply()作为有效的“主”构造函数。

        3
  •  11
  •   Maxim Vladimirsky    14 年前

    另一个选择是将主对象构造函数设为私有,并将配套对象的Apply方法用作生成器。如果我们将(pun不是有意的)这种方法应用于您的示例,它将如下所示:

    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);
    

    这有点冗长,但可能更糟,我想:)。我们希望在将来的scala版本中将私有[this]VAL视为临时变量。马丁自己也暗示过。

        4
  •  6
  •   Andrejs    11 年前

    关于这个话题的一些讨论,包括马丁·奥德斯基的评论,是 here