如果有人能向我解释为什么以下会导致问题,我将不胜感激。我已经创建了一个小例子来证明这个问题:
我有一个项目我用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中的另一个源文件访问它,我不会遇到任何问题,并且我想避免以这种方式更改变量的定义来解决此类问题
由于
答案 0 :(得分:3)
我不知道答案,但研究它很有意思。
显然特质App有点特别
http://www.scala-lang.org/api/current/index.html#scala.App
应该注意的是,这个特性是使用 DelayedInit功能,表示对象的字段将 在主方法执行之前尚未初始化。