开发者

When does a Stream need to be lazy?

开发者 https://www.devze.com 2023-03-26 01:08 出处:网络
The following are both meant to create a Stream of integers: val s: Stream[Int] = 1 #:: s.map(_ + 1) def makeStream = {

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
}

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)
                             ^

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?


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).

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号