2

我有一个深度“嵌套”的理解,简化为以下 3 个级别:x、y 和 z。我希望只做 xaStream也会使 y 和 z 计算变得懒惰:

val stream = for {
  x <- List(1, 2, 3).toStream
  y <- List("foo", "bar", "baz")
  z = {
    println("Processed " + x + y)
    x + y
  }
} yield z

stream take (2) foreach (doSomething)

但这计算了所有 3 个元素,如 3 个打印件所证明的那样。我只想计算前 2 个,因为这些都是我从流中获取的。toStream我可以通过调用第二个等来解决这个List问题。有没有比在理解的每个层面都调用它更好的方法?

4

1 回答 1

4

它打印的是:

Processed 1foo
Processed 1bar
Processed 1baz
stream: scala.collection.immutable.Stream[String] = Stream(1foo, ?)

scala> stream take (2) foreach (println)
1foo
1bar

a 的头部Stream总是被严格评估,这就是为什么你看到Processed 1fooetc 而不是Processed 2fooetc。这是在你创建 Stream 时打印的,或者更准确地说,stream是在评估头部时打印的。

你是对的,如果你只想一个一个地处理每个结果元素,那么所有的生成器都必须是 Streams。toStream您可以通过使它们以 Streams 开头来绕过调用,如下例所示。

stream是 aStream[String]并且它的头部需要被评估。如果您不想急切地计算一个值,您可以预先添加一个虚拟值,或者更好的是,使您的值stream lazy

lazy val stream = for {
  x <- Stream(1, 2, 3)
  y <- Stream("foo", "bar", "baz")
  z = { println("Processed " + x + y); x + y }
} yield z 

在您获取每个值之前,这不会进行任何“处理”:

scala> stream take 2 foreach println
Processed 1foo
1foo
Processed 1bar
1bar
于 2012-03-24T02:57:37.910 回答