Jus*_*ang 3 scope scala lazy-evaluation sbt
我正在阅读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关键字只会延迟初始化?看来这里的值甚至在声明之前都在某种程度上,从不介意初始化......
希望有人能够解释这里发生了什么!
请参阅Scala语言规范的第4章:
声明或定义引入的名称范围是包含绑定的整个语句序列.但是,块中的前向引用存在限制:在组成块的语句序列s 1 ... s n中,如果s i中的简单名称是指由s j定义的实体,其中j≥i,则为s i和s j之间的所有s k,
- s k不能是变量定义.
- 如果s k是值定义,则它必须是惰性的.
换句话说:你可以在lazy vals上有前向引用,但前提是它们之间没有vars或非惰性val.如果你认为lazy val更像是一个方法而不是变量,那么这很直观,并且在REPL上通过两个快速示例:
scala> object o { val a = b; lazy val c = 6; lazy val b = c }
defined module o
scala> o.a
res1: Int = 6
Run Code Online (Sandbox Code Playgroud)
在第一个示例中,Scala a通过调用进行求值,而调用b又调用c哪个求值6.但在下一个例子中,什么时候c不懒...
scala> object o { val a = b; val c = 6; lazy val b = c }
defined module o
scala> o.a
res2: Int = 0
Run Code Online (Sandbox Code Playgroud)
当Scala求值时a,它会调用b,它返回当前值c(当时是0JVM的整数默认值,因为c尚未初始化).然后 c在之后初始化,但到那时为时已晚.
另请参见:如何在Scala 2.10中实现惰性val类变量?
| 归档时间: |
|
| 查看次数: |
522 次 |
| 最近记录: |