Scala初始化顺序(使用scalatest)

Scala initialisation order (using scalatest)

如果有人能向我解释为什么以下原因会导致问题,我将不胜感激。我创建了一个小示例来演示该问题:

我有一个正在使用 sbt 构建的项目,build.sbt 如下:

lazy val root = (project in file(".")).
    settings(
        name := "Test",
        version := "1.0.0",
        scalaVersion := "2.11.5",
        libraryDependencies += "org.scalatest" %% "scalatest" % "2.2.4" % Test
    )

和 Test.scala 在 src/main/scala:

object Test extends App
{
    private val map = Map(1 -> 2)
    def access = map(1)

    println(access)
}

和TestSpec.scala(使用scalatest)在src/test/scala:

import org.scalatest.FlatSpec

class TestSpec extends FlatSpec
{
    "A Test" should "allow access to the map" in
    {
        assert(Test.access == 2)
    }
}

如果我 sbt run 那么 '2' 会按预期打印出来。如果我 sbt test 然后我得到一个 NullPointerException 并且测试失败:

[info] TestSpec:
[info] A Test
[info] - should allow access to the map *** FAILED ***
[info]   java.lang.NullPointerException:
[info]   at Test$.access(Test.scala:4)
[info]   at TestSpec$$anonfun.apply$mcV$sp(TestSpec.scala:7)
etc.

这是因为TestSpec访问时map为null。我可以通过将映射更改为惰性 val 或 def 来解决此问题,但我想更详细地了解这里的初始化顺序以及将来如何避免这种情况。如果我尝试使用 src\main\scala 中的另一个源文件访问它,我没有任何问题,并且我想避免以这种方式更改变量的定义来解决此类问题。

谢谢

我不知道答案,但研究它很有趣。

看来trait App有点特殊

http://www.scala-lang.org/api/current/index.html#scala.App

It should be noted that this trait is implemented using the DelayedInit functionality, which means that fields of the object will not have been initialized before the main method has been executed.