Scala 为什么takeWhile无法与流一起工作
以下代码打印“*1”。令人迷惑的是,如果我删除了它返回的“*4”这是我所期望的Scala 为什么takeWhile无法与流一起工作,scala,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) var max=0 lazy val list:Stream[Int]=1#:::Stream.from(2)
var max = 0
lazy val list: Stream[Int] = 1 #:: Stream.from(2)
list.takeWhile {
x =>
max = x
x < 4
}//.foreach(println)
println("*" + max)
var max=0
lazy val list:Stream[Int]=1#:::Stream.from(2)
list.takeWhile{
x=>
最大值=x
x<4
}//.foreach(println)
println(“*”+最大值)
首先:第二行中的懒惰的
没有做任何事情,您可以删除它并获得相同的结果
更重要的是:takeWhile
实际上是懒惰的,因为它只返回另一个流
,并且在需要之前不会对超过该流头部的任何内容进行评估。考虑以下事项:
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)⇒ 传递给takeWhile
的Boolean
将不会得到流头以外的任何元素,直到像您的foreach
这样的东西成为必要
通过在takeWhile
谓词中添加类似于println
的内容,您可以更显著地看到这一点:
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)
scala>vals=Stream.from(1).takeWhile{x=>println(“检查:+x);x<4}
核对:1
s:scala.collection.immutable.Stream[Int]=流(1,?)
scala>val l=s.toList
支票:2
支票:3
支票:4
l:List[Int]=List(1,2,3)
显然,谓词只会被调用为流的头部,直到我们通过调用toList
强制计算流的其余部分