如果在Scala中,这val foo: Int = 0
会被反编译为:
private[this] val foo_: Int = 0
def foo: Int = foo_
Run Code Online (Sandbox Code Playgroud)
那么如何def
评估它们每次被调用但是val
只被评估一次?既然val
反编译成了def
反正呢?
对于a val
,有一个私有变量("val")和一个getter方法("def").变量用一个值初始化,该值计算一次.
对于a def
,没有变量来"缓存"该值,因此每次都会计算它.
class Foo {
val bar = { println("BAR"); "bar" }
}
Run Code Online (Sandbox Code Playgroud)
大致相当于
class Foo {
private var bar_ = { println("BAR"); "bar" }
def bar = bar_
}
Run Code Online (Sandbox Code Playgroud)
bar_
在创建类的实例时,块初始化仅执行一次.所以,像
val f = new Foo
println("Created")
f.bar
f.bar
f.bar
Run Code Online (Sandbox Code Playgroud)
将打印出"BAR",然后打印"创建",没有别的.
但如果你定义Foo
为
class Foo {
def bar = { println("BAR"); "bar" }
}
Run Code Online (Sandbox Code Playgroud)
然后每次访问时都会对块进行评估bar
,上面的代码将首先打印"已创建",然后打印"BAR" 三次.