Stream什么时候需要懒惰?

Lui*_*hys 12 scala stream lazy-evaluation

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

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

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

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

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

它只会编译,如果我们做s一个lazy val.为什么它需要lazy val在一个方法中,但不在外面?

Kip*_*ros 16

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

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