![](/img/trans.png)
[英]Difference between lazy{} vs getter() initialization in kotlin
[英]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.