scala惰性函数
原生支持惰性,懒加载。
回复java的懒加载
/**
* Java懒加载
*/
public class LayLoad {
private String prop;
public String getProp() {
if (prop == null) {
prop = initProp();
}
return prop;
}
private String initProp() {
return "jimo";
}
}
scala演示
在使用惰性之前
def longJob(): Int = {
println("这是个很耗资源的任务")
1
}
def main(args: Array[String]): Unit = {
val res = longJob()
println("============================")
println(res)
}
结果:先计算
这是个很耗资源的任务
============================
1
假如后面不使用res,也会计算。
使用惰性
lazy val res = longJob()
println("============================")
println(res)
结果:在使用到才加载
============================
这是个很耗资源的任务
1
如何实现的
我们反编译生成的class文件:
LayDemo$.class
public void main(String[] args) {
IntRef res$lzy = IntRef.zero();
VolatileByteRef bitmap$0 = VolatileByteRef.create((byte)0);
scala.Predef$.MODULE$.println("============================");
scala.Predef$.MODULE$.println(BoxesRunTime.boxToInteger(res$1(res$lzy, bitmap$0)));
}
private final int res$lzycompute$1(IntRef res$lzy$1, VolatileByteRef bitmap$0$1) {
synchronized (this) {
if ((byte)(bitmap$0$1.elem & 0x1) == 0) {
res$lzy$1.elem = longJob();
bitmap$0$1.elem = (byte)(bitmap$0$1.elem | 0x1);
}
return res$lzy$1.elem;
}
}
private final int res$1(IntRef res$lzy$1, VolatileByteRef bitmap$0$1) {
return ((byte)(bitmap$0$1.elem & 0x1) == 0) ? res$lzycompute$1(res$lzy$1, bitmap$0$1) : res$lzy$1.elem;
}
意思就是:
- 懒加载的值首先被初始化为零值
- 然后创建了一个bitmap来记录这里有个懒加载,同时这个位为0
- 当使用到时,如果发现没有值(bit位为0),则计算,否则直接返回
注意事项
- lazy只能修饰val变量,不能修饰var变量
- lazy也可以修饰常量:
lazy val = 10