2016-08-24 119 views
1

我寫了下面的代碼使用的Scala流斯卡拉流處理

def foo(x: Int) : Stream[Int] = {println("came inside"); (2 * x)} #:: foo(x + 1) 
foo(1).takeWhile(_ < 6).toList.foreach(x => println(s"+++ $x")) 

這工作,併產生下列輸出

came inside 
came inside 
came inside 
+++ 2 
+++ 4 

,但我想的處理髮生像

came inside 
+++ 2 
came inside 
+++ 4 
came inside 

基本上我想一個接一個地處理,直到終止條件< 6會見。我想它是我的「tolist」方法,它首先創建一個巨大的列表,然後才處理它。

+0

i)你正在定義一個帶有副作用(即'println')的流,這是很難處理和難以推理。 ii)是的,'toList'將「實現流」,所以它會觸發所有的副作用,然後再執行你之後調用的任何東西。 – rsenna

回答

1

首先,以更易讀的方式格式化您的代碼。然後,刪除toList:它所做的只是將整個流引入單個變量。這樣做會強制計算所有值。由於此時每個值都計算在內,因此我們知道「內部」printlns將在「外部」之前執行。你想把你的函數的定義(包括它的起始值)存儲爲一個懶惰的評估值。這應該工作:

def river(x: Int) : Stream[Int] = { 
    println("Inside function.") 
    (2 * x) #:: river(x + 1) 
} 

lazy val creek = river(1) 
creek.takeWhile(_ < 6).foreach(x => println(s"+++ $x"))