2

我是新來的scala和大多數函數式語言,我目前正在試圖分解一個數字。我寫的代碼:在scala中懶惰的理解評估

lazy val factors = for(int <- 2 until math.ceil(math.sqrt(number)).toInt if number%int == 0) yield int 

我在想,如果我宣佈斯卡拉VAL懶惰當我打電話factors.head將它不評估理解整個?

回答

9

你的factors變量是懶惰的; for修真不是。當您第一次訪問factors時,您的for理解將被完全評估。

在斯卡拉,for理解只是一個糖爲flatMap,mapwithFilter方法調用。所以如果你的支持數據結構是嚴格的(比如Range--這就是你正在使用的),你的for理解也將是嚴格的。如果數據結構是懶惰的(如Stream),那麼將會是for的理解。

看出差別:

scala> val number = 50 
number: Int = 50 

scala> lazy val factors = for(int <- 2 until math.ceil(math.sqrt(number)).toInt if number%int == 0) yield int 
factors: scala.collection.immutable.IndexedSeq[Int] = <lazy> 

scala> factors.head 
res5: Int = 2 

scala> factors 
res6: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 5) 

scala> lazy val factors = for(int <- Stream.range(2, math.ceil(math.sqrt(number)).toInt - 1) if number%int == 0) yield int 
factors: scala.collection.immutable.Stream[Int] = <lazy> 

scala> factors.head 
res7: Int = 2 

scala> factors 
res8: scala.collection.immutable.Stream[Int] = Stream(2, ?) 
1

不,這是完全不同的事情:lazy表示該值是在您第一次訪問它時計算的。如果要爲集合執行延遲計算,則應使用Stream或使用視圖。 A Stream可以使用view從集合中構建。