Stream 啥时候需要惰性?

Posted

技术标签:

【中文标题】Stream 啥时候需要惰性?【英文标题】:When does a Stream need to be lazy?Stream 什么时候需要惰性? 【发布时间】:2011-10-21 05:22:56 【问题描述】:

以下内容均用于创建整数流:

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】:

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

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

【讨论】:

以上是关于Stream 啥时候需要惰性?的主要内容,如果未能解决你的问题,请参考以下文章

Java 啥时候需要显式类型参数?

Stream01 定义迭代操作惰性求值

Scala编程之惰性函数

Java8新特性----Stream

惰性载入函数

Django惰性加载和LazyObject