Stream何时需要变得懒惰? [英] When does a Stream need to be lazy?

查看:61
本文介绍了Stream何时需要变得懒惰?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The following are both meant to create a Stream of integers:

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

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

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

The first is fine; however the makeStream method won't compile:

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

仅当我们将s设为lazy val时才编译.为什么它必须在方法中是lazy val而不是外部?

It only compiles if we make s a lazy val. Why does it need to be a lazy val in a method, but not outside?

推荐答案

在类内部,val定义反编译为引用隐藏类字段的"getter"方法.这些获取器"方法可以是自引用的(或者类初始化器可以引用获取器"),因为这是Java方法的语义.请注意,您的val s的外部"定义实际上是由REPL包裹在一个隐藏类中的(这是REPL规避了不能在顶级声明val的限制)的方法.

Inside a class, a val definition decompiles into an "getter" method that references a hidden class field. These "getter" methods can be self-referential (or rather, the class initializer can reference the "getter") because this is the semantics of Java methods. Note that your "outside" definition of val s is actually wrapped in a hidden class by the REPL (this is how the REPL circumvents the restriction that a val can't be declared at the top level).

在方法内部,val定义不会反编译为"getter"方法,而是反编译为在堆栈上生成值所必需的字节码.另一方面,lazy val始终需要一种"getter"方法,因此该方法可以是自引用的.

Inside a method, the val definition does not decompile into a "getter" method, but rather into the bytecode necessary to generate a value on the stack. A lazy val, on the other hand, always requires a "getter" method which, as such, can be self-referential.

这篇关于Stream何时需要变得懒惰?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆