3

我明白vallazy val之間的差異基本。 雖然我遇到這個例子,但我很困惑。lazy val v.s. val在斯卡拉的遞歸流

以下代碼是正確的。它是一個流類型延遲值的遞歸。

def recursive(): { 
    lazy val recurseValue: Stream[Int] = 1 #:: recurseValue.map(_+1) 
    recurseValue 
} 

如果我將lazy val更改爲val。它報告錯誤。

def recursive(): { 
    //error forward reference failed. 
    val recurseValue: Stream[Int] = 1 #:: recurseValue.map(func) 
    recurseValue 
} 

我的替代模式在二路例如思想的痕跡/評估策略是:

右手視線#::的是呼叫名字與該值應爲以下形式:

1 #:: ?

,如果後來被訪問二路元件時,它是指當前recurseValue值,並將其改寫到:

1 :: ((1 #:: ?) map func) = 1 :: (func(1) #:: (? map func))

....等等等等,使得編譯器應該成功。

我沒有看到任何錯誤,當我重寫它,有什麼問題嗎?

編輯: 結論:我發現它工作正常,如果val定義爲一個字段。我也注意到這個關於val的實現的這個post。結論是val在方法或字段或REPL中有不同的實現。這真是令人困惑。

+0

懶VAL允許向前引用,而不允許非本地懶VAL。懶惰的val實際上不直接引用任何東西,它在稍後調用時引用它。 – jilen

+0

REPL逐一計算每一行。所以,每一個懶惰的val都會立即被訪問。 http://daily-scala.blogspot.ru/2009/09/lazy-val.html – gayavat

回答

2

即替代模式適用於遞歸如果要定義功能,但你不能用自身的定義變量除非是懶惰。計算右側所需的所有信息必須可用於分配,因此爲了遞歸定義變量需要一些懶惰。

You probably don't really want to do this,而只是表明它適用於功能:

scala> def r = { def x:Stream[Int] = 1#::(x map (_+1)); x } 
r: Stream[Int] 
scala> r take 3 foreach println 
1 
2 
3 
+0

好的謝謝。是的,如果將val定義爲字段,我發現它確實工作正常。我也注意到這個關於val實現的帖子。結論是val在方法或字段或REPL中有不同的實現。這真是令人困惑。 –