编辑:我不确定MikaëlMayer的回答是否能解释所有内容。考虑:
object Test {
def main(args: Array[String]) {
println(x)
lazy val x: Int = 6
}
}
在这里,在代码中实际定义了惰性值
x
之前,绝对必须对其进行读取/评估!这与Mikaël所说的懒惰评估消除了在定义事物之前评估事物的需求相抵触。 最佳答案
通常,您不能拥有以下功能:
val e: Int = 2
val a: Int = b+c
val b: Int = c
val c: Int = 1
val d: Int = 0
因为在定义a时尚未定义值c。因为引用c,所以a和c之间的所有值都应该是惰性的,这样可以避免依赖关系
val e: Int = 2
lazy val a: Int = b+c
lazy val b: Int = c
lazy val c: Int = 1
val d: Int = 0
实际上,这会将a,b和c转换为对象,这些对象的值在读取后即在声明之后初始化,即等同于:
val e: Int = 2
var a: LazyEval[Int] = null
var b: LazyEval[Int] = null
var c: LazyEval[Int] = null
a = new LazyEval[Int] {
def evalInternal() = b.eval() + c.eval()
}
b = new LazyEval[Int] {
def evalInternal() = c.eval()
}
c = new LazyEval[Int] {
def evalInternal() = 1
}
val d = 0
其中
LazyEval
将类似于以下内容(由编译器本身实现)class LazyEval[T] {
var value: T = _
var computed: Boolean = false
def evalInternal(): T // Abstract method to be overriden
def eval(): T = {
if(computed) value else {
value = evalInternal()
computed = true
value
}
}
}
编辑
val在Java中并不真正存在。它们是局部变量或在计算中不存在。因此,在完成任何操作之前都存在lazy val的声明。请记住,闭包是在Scala中实现的。
您的代码块将被重写为:
对象测试{
def main(args:Array [String]){
//声明所有变量val和vars。
var x:Lazy [Int] = null
//没有更多要声明的变量。懒惰/或非变量定义
x =新的LazyEval [Int] {
def evalInternal()= 6
}
//现在代码开始
println(x)
}
}