什么时候一个流需要被惰性化?



下面两个语句都是用来创建一个整数流:

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,而在方法外部不需要?

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

在方法内部,val定义不会反编译成"getter"方法,而是编译成在堆栈上生成值所需的字节码。另一方面,lazy val总是需要一个"getter"方法,因此,它可以是自引用的。

最新更新