【问题标题】:Scala 2.8: how to initialize child classScala 2.8:如何初始化子类
【发布时间】:2023-03-07 01:05:01
【问题描述】:

考虑以下代码:

abstract class X {
  def a:Unit
  a
}

class Y extends X {
  var s:String = "Hello"
  def a:Unit = println ("String is "+s)
}

这给出以下输出:

scala> new Y
String is null
res6: Y = Y@18aeabe

如何让父类X在调用a时等待s被初始化

【问题讨论】:

    标签: scala scala-2.8


    【解决方案1】:

    父字段和父构造函数总是在子字段和构造函数之前初始化和运行。这意味着对a 的调用发生在您的var s 在子类中设置之前。

    一般来说,从构造函数调用虚方法是个坏主意; C++ 甚至不允许它(或者,当从超类的构造函数调用时,不调用在子类中实现的方法,而不是不允许它)。

    但是,如果您将 class Y 中的 var s 改为 lazy valdef,则可以解决此问题。 lazy vals 在第一次访问它们的值时被初始化,无论是谁; defs 没有像 vars 或 vals 这样的初始化问题。但是,请注意不要在 a 的实现中调用任何其他未初始化的结构,因为同样的问题会再次出现。

    编辑:

    您还可以使用 Scala 的“早期定义”(或早期初始化)功能:

    class Y extends {
      var s = "Hello"
    } with X {
      def a: Unit = println ("String is "+s)
    }
    

    【讨论】:

    • 我需要 s 成为 var,因为它稍后会在我的代码中进行修改。因此,defval 都不起作用。
    • 谢谢。早期定义功能很有趣。
    • 你能退后一步,多说一下你想要做什么,而不是你想怎么做吗?
    • 为什么Scala不支持lazy var
    • 有一个关于here的讨论。
    猜你喜欢
    • 2012-03-07
    • 1970-01-01
    • 2021-03-23
    • 1970-01-01
    • 2020-09-09
    • 2018-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多