Это то, что вы имели:
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) импорт не вызывает инициализации.
Импорт никогда не имеет эффектов. –