When does a Stream need to be lazy?

独自空忆成欢 提交于 2019-12-21 03:43:28

问题


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?


回答1:


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.



来源:https://stackoverflow.com/questions/6962778/when-does-a-stream-need-to-be-lazy

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!