2015-09-01 83 views
0

鑑於相關:初始化對象在另一個對象

的src/main /斯卡拉/ NET/Foo.scala

package net 

object Foo { 
    ??? 
    val x = 100 
} 

的src/main /斯卡拉/ NET/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

這是你有什麼:

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必須在這一點上初始化 - 斯卡拉在這裏懶惰。 現在用這個例子對比:

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因爲其在自己的初始化而這又是 調用speak觸發使用Foo.x得到初始化。簡化示例:

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)進口不會導致初始化。

2

因爲Bar實際上並不指Foo任何地方。如果Bar.speak以某種方式使用FooFoo.x,您將得到預期的例外。 importFoo的成員放入範圍,但不訪問它們。