本文介绍了为什么我的 takeWhile 无法与我的 Stream 一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码打印*1".令人困惑的是,如果我删除评论,它会返回*4",这正是我所期待的

The following code prints "*1". What's mystifying is if I remove the comment it returns "*4" which is what I was expecting

var max = 0
lazy val list: Stream[Int] = 1 #:: Stream.from(2)
list.takeWhile {
  x =>
    max = x
    x < 4
}//.foreach(println)
println("*" + max)

推荐答案

首先:第二行中的 lazy 没有做任何事情——你可以删除它并获得相同的结果.

First of all: the lazy in your second line isn't doing anything—you can remove it and get the same result.

更重要的是:takeWhile实际上是懒惰的,因为它只返回另一个Stream,并且没有超过那个流的头部评估直到需要.考虑以下几点:

More importantly: takeWhile is actually lazy, in that it just returns another Stream, and nothing past the head of that stream will be evaluated until it's needed. Consider the following:

val s = Stream.from(1).takeWhile(_ > 0)

你和我都知道 s 将是一个无限流,但如果我们启动 REPL 并输入它,很高兴评估它:

You and I know that s is going to be an infinite stream, but if we fire up the REPL and type this in, it's perfectly happy to evaluate it:

scala> val s = Stream.from(1).takeWhile(_ > 0)
s: scala.collection.immutable.Stream[Int] = Stream(1, ?)

在您的示例中发生了同样的事情:您传递给 takeWhile(Int) ⇒ Boolean 不会被提供给超出流的头部,直到您的 foreach 之类的东西使之成为必需.

The same thing is happening in your example: the (Int) ⇒ Boolean that you've passed to takeWhile isn't going to get fed any elements beyond the head of the stream, until something like your foreach makes that necessary.

通过在 takeWhile 谓词中添加类似 println 之类的内容,您可以更显着地看到这一点:

You can see this even more dramatically by adding something like a println inside of the takeWhile predicate:

scala> val s = Stream.from(1).takeWhile { x => println("Checking: " + x); x < 4 }
Checking: 1
s: scala.collection.immutable.Stream[Int] = Stream(1, ?)

scala> val l = s.toList
Checking: 2
Checking: 3
Checking: 4
l: List[Int] = List(1, 2, 3)

显然只对流的头部调用谓词,直到我们通过调用 toList 强制对流的其余部分进行评估.

Clearly the predicate only gets called for the head of the stream, until we force the evaluation of the rest of the stream by calling toList.

这篇关于为什么我的 takeWhile 无法与我的 Stream 一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 11:44