2011-08-05 90 views
12

下都意味着創造整數流:什麼時候需要偷懶?

val s: Stream[Int] = 1 #:: s.map(_ + 1) 

def makeStream = { 
    val s: Stream[Int] = 1 #:: s.map(_ + 1) 
    s 
} 

首先是罰款;然而makeStream方法不會編譯:

error: forward reference extends over definition of value s 
    val s: Stream[Int] = 1 #:: s.map(_ + 1) 
          ^

如果我們s一個lazy val它只編譯。爲什麼它需要在方法中成爲lazy val,但不是外部?

回答

16

在類中,val定義反編譯爲引用隱藏類字段的「getter」方法。這些「getter」方法可以是自引用的(或者說,類初始化程序可以引用「getter」),因爲這是Java方法的語義。請注意,val s的「外部」定義實際上由REPL包裝在隱藏類中(這是REPL繞過無法在頂層聲明val的限制)。

在一個方法中,val定義不會反編譯爲「getter」方法,而是編譯爲在堆棧中生成值所需的字節碼。另一方面,A lazy val總是需要「吸氣」方法,因此它可以是自引用的。

相關問題