Lui*_*hys 10 scala stream lazy-evaluation
通常,如果您创建一个Stream对象,则会热切地评估头部:
scala> Stream( {println("evaluating 1"); 1} , 2, 3)
evaluating 1
res63: scala.collection.immutable.Stream[Int] = Stream(1, ?)
Run Code Online (Sandbox Code Playgroud)
如果我们创建一个我们在同一语句中添加的Stream,那么在连接之前不会对头进行求值似乎有点令人惊讶.即
scala> 0 #:: Stream( {println("evaluating 1"); 1} , 2, 3)
res65: scala.collection.immutable.Stream[Int] = Stream(0, ?)
Run Code Online (Sandbox Code Playgroud)
(#::是右关联的,是prepend方法ConsWrapper,它是一个隐式类Stream.)
在预先设定0之前,这怎么不评价它的头?在我们从结果流中获取值之前,堆尾流(或缺点单元格)是否存在于堆中?但如果是这样,我们如何#::在一个不存在的对象上调用该方法呢?
-Xprint:typer 是你的朋友,任何时候你想要准确理解一些代码是如何评估或推断类型的.
scala -Xprint:typer -e '0 #:: Stream( {println("evaluating 1"); 1} , 2, 3)'
val x$1: Int = 0;
Stream.consWrapper[Int](Stream.apply[Int]({
println("evaluating 1");
1
}, 2, 3)).#::(x$1)
Run Code Online (Sandbox Code Playgroud)
参数consWrapper是按名称.所以即使这样工作:
scala> (1 #:: (sys.error("!!"): Stream[Int])).head
res1: Int = 1
Run Code Online (Sandbox Code Playgroud)
在创建Stream时评估头部.
但是在第二个示例中,您没有传递Streem作为#::传递by name参数的第二个参数,即Stream( {println("evaluating 1"); 1} , 2, 3)根本不评估完整表达式.
| 归档时间: |
|
| 查看次数: |
370 次 |
| 最近记录: |