kotlin 中 val 的动态惰性初始化

Dynamic lazy initialization for val in kotlin

我知道在 kotlin 中有两种延迟初始化的方法。首先是 lateinit,它是动态的,但仅适用于 var。其次,通过 lazy 代表 val 但它是 static,这意味着它不能在运行时初始化。
我想知道有没有办法对不可变属性进行延迟动态初始化(val)?????

属性 委托也像 lazy 一样工作,即使我们定义了自定义委托,它也始终是静态初始化。 (据我所知)

有解决办法吗?能以某种方式实施吗?
所以我希望的是 lateinit val,如下代码所示:

class MyClass: SomeCallback {
    
    private lateinit val myData: String
    
    override fun onStatusChanged(status: Status, data: String) {
        if(status == Status.DataConfirmed ) {
            myData = data
        }
    }

}

我能想出的最好办法是读写 属性 委托,如果您在设置它之前访问它,或者如果您多次设置它,它就会抛出。 Kotlin 不会让你 lateinit 一个 val。这可能是因为为没有 属性 调用 setter 是荒谬的。我怀疑他们想引入蠕虫罐头,即直接从初始化程序以外的任何地方设置支持字段的值,因为这会产生歧义。

像这样的代表应该足够了。如果它不足以帮助您立即修复多次调用 setter 的错误,我会说这是一种代码味道,因为 class 太复杂了,需要分解成更小的单元。

class Once<T>: ReadWriteProperty<Any, T> {
    private object UNINITIALIZED
    private var _value: Any? = UNINITIALIZED

    override fun getValue(thisRef: Any, property: KProperty<*>): T {
        if (_value !== UNINITIALIZED) {
            @Suppress("UNCHECKED_CAST")
            return _value as T
        }
        throw UninitializedPropertyAccessException("Property [$property] was accessed before it was initialized.")
    }

    override fun setValue(thisRef: Any, property: KProperty<*>, value: T) {
        if (_value === UNINITIALIZED) {
            _value = value
        } else {
            error("Cannot set property [$property] more than once.")
        }
    }
}