Stream什么时候需要懒惰?

时间:2011-08-05 21:20:45

标签: scala stream lazy-evaluation

以下两个都是为了创建一个整数流:

val s: Stream[Int] = 1 #:: s.map(_ + 1)

def makeStream = {
  val s: Stream[Int] = 1 #:: s.map(_ + 1)
  s
}

第一个很好;但是makeStream方法不会编译:

error: forward reference extends over definition of value s
  val s: Stream[Int] = 1 #:: s.map(_ + 1)
                             ^

只有在s成为lazy val时才会进行编译。为什么它必须是方法中的lazy val,而不是外部?

1 个答案:

答案 0 :(得分:16)

在类中,val定义反编译为引用隐藏类字段的“getter”方法。这些“getter”方法可以是自引用的(或者更确切地说,类初始化器可以引用“getter”),因为这是Java方法的语义。请注意,val s的“外部”定义实际上是由REPL包装在一个隐藏的类中(这就是REPL规避了不能在顶层声明val的限制的方式)。

在方法内部,val定义不会反编译为“getter”方法,而是反编译为在堆栈上生成值所需的字节码。另一方面,lazy val总是需要一种“吸气剂”方法,因此可以自我指导。