Stream何时需要变得懒惰? [英] When does a Stream need to be lazy?
问题描述
以下内容均用于创建整数流:
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屋!