2016-08-24 89 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"))