首页 > 解决方案 > Scala 奇怪的类/对象初始化

问题描述

我找不到为什么此代码会引发异常的答案assertProperChildren(Zoo2),但前提Zoo2.Tiger是在进行断言之前访问了该异常。如果您评论该访问行,则所有断言都有效。对我来说没有意义。这是一个已知的 Scala 错误吗?

trait Domain {
  abstract class ChildDomain
  def children: Seq[ChildDomain]
}

// V1
abstract class Zoo1 extends Domain {
  object Tiger extends ChildDomain
  val children = Seq(Tiger)
}
object Zoo1 extends Zoo1

// V2
object Zoo2 extends Domain {
  object Tiger extends ChildDomain
  val children = Seq(Tiger)
}

// V3
object Zoo3 extends Domain {
  object Tiger extends ChildDomain
  lazy val children = Seq(Tiger)
}

object Main {
  def main(args: Array[String]): Unit = {
    def assertProperChildren(domain: Domain) = {
      assert(!domain.children.contains(null))
    }
    Zoo1.Tiger
    // Will NOT crash here, even if we touch Zoo1.Tiger before Zoo1
    assertProperChildren(Zoo1)
    Zoo2.Tiger
    // Will crash here, but only if we touch Zoo2.Tiger before Zoo2
    assertProperChildren(Zoo2)
    // So if we want a scala object directly inheriting from a Domain
    // we need lazy children:
    Zoo3.Tiger
    assertProperChildren(Zoo3)
  }
}

标签: scala

解决方案


Scala 遵循初始化顺序,它在下面的链接中作为常见问题解答进行了解释。 https://docs.scala-lang.org/tutorials/FAQ/initialization-order.html

您可以将-Xcheckinit其用作 scalac 标志的一部分。验证相同。


推荐阅读