3

我一直认为 scala 对象只是单例 java 对象的简写——也就是说,我希望它们表现得像具有保证单例实例化的对象。然后我遇到了这样的事情,我不明白:

object Test  extends App{
 var x ="a"

 override def main(args:Array[String]):Unit = {
   println(x )
 }
}

它打印null而不是“a”。

查看生成的类,我得到一个 Test$.class ,它是对象定义;然而,实例值“a”是使用生成的delayedInit 在伴随的Test 类中定义的。有人可以阐明这是如何实例化的吗?显然,我对此的心智模型是不正确的。

4

1 回答 1

4

让我们先来看看App它是如何工作的。App的文档揭示了以下警告:

需要注意的是,这个 trait 是使用 DelayedInit功能实现的,这意味着对象的字段在 main 方法执行之前不会被初始化。

还应该注意的是,main 方法通常不需要被覆盖:目的是将整个类体变成“main 方法”。如果您知道自己在做什么,您应该只选择覆盖它。

你的例子

好的,不错。现在我们知道了这两个事实,让我们修复您的代码。我们可以考虑两种可能的解决方案:

当我们知道我们在做什么时,让我们只覆盖 main 方法:

object Test extends App{
 var x ="a"
 println(x )
}

或者我们可以选择定义一个main方法,但不能扩展App

object Test {
 var x ="a"

 def main(args:Array[String]):Unit = {
   println(x )
 }
}

结论

你对对象的理解是正确的。令人困惑的是实现的DelayedInitApp。快乐编码;)

于 2013-11-13T00:53:22.160 回答