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