繁体   English   中英

kotlin 中 val 的动态延迟初始化

[英]Dynamic lazy initialization for val in kotlin

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

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

有解决方法吗? 它可以以某种方式实施吗?
所以我想要的是类似于lateinit val的东西,如下面的代码所示:

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

}

我能想到的最好的方法是一个读写属性委托,如果你在设置它之前访问它,或者如果你设置它多次。 lateinit不允许您延迟初始化val 这可能是因为为没有 setter 的属性调用 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.")
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM