Scala流评估

时间:2017-07-21 21:04:52

标签: scala stream

假设我有这段代码

val stream = Stream.continually(1)
val s = stream.take(10).map(i => {
  throw new RuntimeException
  i
})

据我所知,当访问流s中的相应元素时,将评估传递给map的函数。如果s从未迭代过并且没有访问过任何元素,为什么会抛出异常?

2 个答案:

答案 0 :(得分:4)

始终评估Stream的第一个元素。

这将永远抛出。

val stream = Stream.iterate(0)(_ + 1)
val s = stream.take(10).map(i => {
  if (i == 0) throw new RuntimeException
  i
})

但是在引用s(1)之前不会这样做。

val stream = Stream.iterate(0)(_ + 1)
val s = stream.take(10).map(i => {
  if (i > 0) throw new RuntimeException
  i
})

答案 1 :(得分:0)

第一次评估,

scala> val stream = Stream.continually(1)
stream: scala.collection.immutable.Stream[Int] = Stream(1, ?)

scala> val newStream = stream.take(10).zipWithIndex.map{case (value, index) => { println(s"processing ${index}"); value * 2 } }
processing 0
newStream: scala.collection.immutable.Stream[Int] = Stream(2, ?)

因此,在您的情况下抛出异常,因为它首次评估

scala> val newStream = stream.take(10).zipWithIndex.map{case (value, index) => { println(s"processing ${index}"); throw new Exception; value * 2 } }
processing 0
java.lang.Exception
  at .$anonfun$newStream$1(<console>:12)
  at .$anonfun$newStream$1$adapted(<console>:12)
  at scala.collection.immutable.Stream.map(Stream.scala:415)
  ... 29 elided

您可以通过仅在第一次添加支票时进行验证,如下所示

scala> val newStream = stream.take(10).zipWithIndex.map{case (value, index) => { println(s"processing ${index}"); if(index > 0 ) throw new Exception; value * 2 } }
processing 0
newStream: scala.collection.immutable.Stream[Int] = Stream(2, ?)