假设:
的src /主/阶/净/ Foo.scala
package net
object Foo {
???
val x = 100
}
的src /主/阶/净/ Bar.scala
package net
object Bar {
import Foo._
def speak = "bar!"
}
我打开了REPL来拨打Bar#speak
:
scala> import net.Bar
import net.Bar
scala> Bar.speak
res0: String = bar!
我原本希望Bar初始化Foo
,导致???
抛出异常。
为什么没有抛出这个异常?
答案 0 :(得分:2)
因为Bar
实际上并未在任何地方引用Foo
。如果Bar.speak
以某种方式使用Foo
或Foo.x
,您将获得预期的异常。 import
将Foo
个成员放入范围,但无法访问它们。
答案 1 :(得分:2)
这就是你所拥有的:
scala> object Foo {
| ???
| val x = 100
| }
defined object Foo
scala> object Bar {
| import Foo._
| def speak = "bar!"
| }
defined object Bar
scala> Bar.speak
res0: String = bar!
scala> Bar.speak
res1: String = bar!
import Foo._
表示为了编译目的,解析名称Foo的成员将在范围内可用。
这并不意味着此时必须初始化Foo
- Scala在这里很懒惰。
现在与这个例子形成鲜明对比:
scala> object Foo {
| ???
| val x = 100
| }
defined object Foo
scala> object Bar {
| val blowUp = Foo.x
| def speak = "bar!"
| }
defined object Bar
scala> Bar.speak
scala.NotImplementedError: an implementation is missing
at scala.Predef$.$qmark$qmark$qmark(Predef.scala:225)
... 37 elided
强制Foo
初始化,因为它在自己的初始化中使用Foo.x
,而初始化又由{
致电speak
。简化示例:
scala> object Foo {
| ???
| val x = 100
| }
defined object Foo
还没爆发。 Foo
未初始化。
scala> Foo.x
scala.NotImplementedError: an implementation is missing
at scala.Predef$.$qmark$qmark$qmark(Predef.scala:225)
... 35 elided
现在我们强制Foo
初始化。
简而言之,这里有两个重要的事情:1)引用/调用时的惰性初始化和2)导入不会导致初始化。