Scala中Val、def、lazy val的实例化顺序及代码输出解析
Scala中val、def、lazy val的执行逻辑详解(附代码输出分析)
先把待分析的代码贴出来:
def deflazyval() : Unit = { lazy val l : Int ={print("l") ; 5} def d : Int ={print("d") ; 7} val v : Int ={print("v") ; 3} var s : Int = d s += l s += v s += l s += d }
先搞懂三个核心元素的特性
- def(方法):每次被调用时都会完整执行一遍代码块,返回新的计算结果,不存在缓存。
- val(普通值):在定义的那一刻就会立即执行代码块,算出结果后永久固定,后续引用直接用缓存的结果,不会再跑代码块。
- lazy val(懒加载值):定义时完全不执行代码块,第一次被引用时才会执行代码块并缓存结果,之后再引用就直接用缓存值,不会重复执行。
逐步骤拆解执行过程
调用deflazyval()后,整个流程的执行顺序和输出变化如下:
变量定义阶段
- 声明
lazy val l:只是注册了这个变量,代码块{print("l") ; 5}完全不执行,无任何输出。 - 声明
def d:只是定义了方法逻辑,方法体{print("d") ; 7}不执行,无输出。 - 声明
val v:立即执行代码块,打印v,并把结果3赋值给v,此时输出内容为v。
- 声明
变量s的操作阶段
var s : Int = d:调用方法d,执行其代码块,打印d,返回7给s。此时输出变为vd。s += l:第一次引用lazy val l,执行其代码块,打印l,返回5,s更新为7+5=12。此时输出变为vdl。s += v:引用val v,直接用之前缓存的3,不会重复执行代码块,无新输出,s更新为12+3=15。输出仍为vdl。s += l:再次引用lazy val l,直接用第一次缓存的5,不执行代码块,无新输出,s更新为15+5=20。输出还是vdl。s += d:再次调用方法d,执行其代码块,打印d,返回7,s更新为20+7=27。此时输出最终变为vdld。
为什么输出是vdld?
v是普通val,定义时直接执行打印,是第一个输出。- 第一次调用
d方法,执行打印,输出追加d。 - 第一次引用
lazy val l,触发打印,输出追加l。 - 后续引用
v和l都用缓存值,不会产生新输出。 - 第二次调用
d方法,再次执行打印,输出追加d,最终得到vdld。
内容的提问来源于stack exchange,提问作者IGG
相关产品推荐
相关产品推荐

