Scala初始化顺序(使用scalatest)

时间:2015-03-17 13:29:51

标签: scala sbt 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
    )

和src / main / scala中的Test.scala:

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

    println(access)
}
src / test / scala中的

和TestSpec.scala(使用scalatest):

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$1.apply$mcV$sp(TestSpec.scala:7)
etc.

这是因为当TestSpec访问它时map为null。我可以通过将地图更改为懒惰的val或def来解决这个问题,但我想知道更多有关此处初始化顺序的详细信息,以及如何避免这种情况未来的事情。如果我尝试使用src \ main \ scala中的另一个源文件访问它,我不会遇到任何问题,并且我想避免以这种方式更改变量的定义来解决此类问题

由于

1 个答案:

答案 0 :(得分:3)

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

显然特质App有点特别

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

  

应该注意的是,这个特性是使用   DelayedInit功能,表示对象的字段将   在主方法执行之前尚未初始化。