Scala的一个便利功能是lazy val,a的评估val被延迟到必要时(首次访问时).
当然,lazy val必须有一些开销 - 在某处Scala必须跟踪该值是否已经被评估并且评估必须同步,因为多个线程可能会尝试同时第一次访问该值.
a的成本到底是什么?lazy val是否有一个隐藏的布尔标志与a关联,lazy val如果它已经被评估,是什么同步,是否有更多的成本?
另外,假设我这样做:
class Something {
lazy val (x, y) = { ... }
}
Run Code Online (Sandbox Code Playgroud)
这是否与两个单独的lazy vals 相同x,y或者我只获得一次开销,对于该对(x, y)?
我正在阅读sbt文档,我在多项目构建一节中遇到了这个例子:
import sbt._
import Keys._
object HelloBuild extends Build {
lazy val root = Project(id = "hello",
base = file(".")) aggregate(foo, bar)
lazy val foo = Project(id = "hello-foo",
base = file("foo"))
lazy val bar = Project(id = "hello-bar",
base = file("bar"))
}
Run Code Online (Sandbox Code Playgroud)
我想知道如何在声明值之前引用值foo和bar?我认为它与lazy关键字有关,但是从我的阅读中,我认为lazy关键字只会延迟初始化?看来这里的值甚至在声明之前都在某种程度上,从不介意初始化......
希望有人能够解释这里发生了什么!
我已经注意到,我几乎完全使用lazy val分配,因为他们往往避免不必要的计算,我不能看到,许多情况下一个会不会想这样做(在可变的变量是当然的一个明显的例外依赖).
在我看来,这是函数式编程的一大优势,应尽可能鼓励它的使用,如果我理解正确,Haskell默认情况下就是这样做的.
那么为什么Scala值默认不是懒惰?是否仅仅是为了避免与可变变量相关的问题?