Scala中惰性VAL的作用域规则是什么?
我在阅读sbt文档时,在多项目构建一节中遇到了这个示例:Scala中惰性VAL的作用域规则是什么?,scala,scope,sbt,lazy-evaluation,Scala,Scope,Sbt,Lazy Evaluation,我在阅读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",
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"))
}
我想知道在声明foo和bar之前,如何引用它们?我认为这与lazy关键字有关,但从我的阅读来看,我认为lazy关键字只是延迟了初始化?这里的值似乎在声明之前就在范围内,更不用说初始化了
希望有人能解释这里发生了什么 就像在Java中一样,类实例变量(或scala val)在包含类/对象的任何部分中都“在范围内”,而不管它在哪里声明 也就是说,它不会被引用它并在声明点之前运行的任何代码“初始化”。惰性val的代码不会在其声明的点运行,因此这是安全的。请参阅: 声明或定义引入的名称的范围是包含绑定的整个语句序列。然而,对块中的前向引用有一个限制:在语句序列s1中。。。构成区块的sn,如果si中的简单名称指sj定义的实体,其中j≥ i、 然后对于si和sj之间的所有sk
- sk不能是变量定义
- 如果sk是一个价值定义,那么它一定是懒惰的
scala> object o { val a = b; lazy val c = 6; lazy val b = c }
defined module o
scala> o.a
res1: Int = 6
在第一个示例中,Scala通过调用b
来计算a
,后者依次调用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
当Scala计算a
时,它调用b
,返回c
的当前值(此时为0
,JVM的默认整数值,因为c
尚未初始化)。然后c
随后被初始化,但到那时已经太晚了
另请参见:精彩的解释!这正是我要寻找的。如果你想一想,这与包含静态变量的Java类和作为静态方法的
lazy VAL
非常相似。它给出了完全相同的结果behavior@Jatin不,惰性VAL是基于实例缓存的。即使实例是一个单例。@som snytt显然是。我的意思是关于行为和初始化这真是个骗局。2008年的搞笑语录:显然人们似乎没有注意到之前关于这个主题的所有信息。我还没有看过“Scala中的编程”的最新草案,但显然它需要用24pt粗体文本讨论初始化,这样人们就不会一遍又一遍地问这个问题。