[Kotlin] 懒加载Lazy<T>简介与应用


简介

Lazy的源码

接口

public interface Lazy {
    public val value: T
    public fun isInitialized(): Boolean
}

一种实现

internal class UnsafeLazyImpl(initializer: () -> T) : Lazy, Serializable {
    private var initializer: (() -> T)? = initializer
    private var _value: Any? = UNINITIALIZED_VALUE

    override val value: T
        get() {
            if (_value === UNINITIALIZED_VALUE) {
                _value = initializer!!()
                initializer = null
            }
            @Suppress("UNCHECKED_CAST")
            return _value as T
        }

    override fun isInitialized(): Boolean = _value !== UNINITIALIZED_VALUE

可以看出,基本原理就是在第一次取值的时候调用initializer函数获得其值,并存储以备下次使用

应用

最简单的方式是调用lazy函数,它接收一个 ()->T 的参数
然后通过.value属性(getValue)来获得值

val x :Lazy = lazy {  -> readln().toInt() }
println("lazy done");
println(x.value);

结果为先输出"lazy done"再要求输入

使用语法糖

val x by lazy { readln().toInt() }
println("lazy done")
println(x)

至于by的用法,涉及委托模式,大致相当于

    val openMsgBox = object {
        val rem = by { mutableStateOf(true) }
        fun getValue() = rem.value
        fun setValue(n :Boolean) {
            rem.value = n
        }
    }