scala - 为什么我的takeWhile无法与我的Stream一起使用

标签 scala

以下代码打印“* 1”。令人惊讶的是,如果我删除注释,它将返回“* 4”,这正是我所期望的

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

最佳答案

首先:第二行中的lazy没有做任何事情-您可以将其删除并获得相同的结果。

更重要的是:takeWhile实际上是惰性的,因为它仅返回另一个Stream,并且直到需要它时,才会评估该流的开头之外的任何内容。考虑以下:

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

您和我都知道s将会是一个无限的流,但是如果我们启动REPL并输入它,那么很乐意对其进行评估:
scala> val s = Stream.from(1).takeWhile(_ > 0)
s: scala.collection.immutable.Stream[Int] = Stream(1, ?)

在您的示例中发生了同样的事情:传递给(Int) ⇒ BooleantakeWhile不会在流头之外获取任何元素,直到foreach之类的东西使这成为必要。

通过在println谓词内添加类似takeWhile的内容,您可以更加生动地看到这一点:
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强制对流的其余部分进行求值。

关于scala - 为什么我的takeWhile无法与我的Stream一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7923999/

相关文章:

scala - 如何从 Scala 集合中的索引获取选项?

scala - 生产代码中的流

scala - 如何在 Azure 中的 Kubernetes 中进行 scala 堆转储

scala - 如何使用 scala 内部构件比 fsc 更快地编译源代码(快速 scala 编译器)

scala - Spark 2.0 隐式编码器,当类型为 Option[Seq[String]] 时处理缺失列(scala)

java - 如何诊断或检测 Java 静态初始化程序中的死锁

scala - Spark Dataframe 更新插入到 Elasticsearch

eclipse - Eclipse中的Scala编辑器不起作用

scala - play 框架 - build.sbt 中的错误解析表达式

java - 类型与类型定义的交集