我了解在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
}
}
}
答案 0 :(得分:2)
我能想到的最好的方法是读写属性委托,如果您在设置它之前访问它或者多次设置它,就会抛出该委托。 Kotlin不允许您lateinit
和val
。这可能是因为为没有属性的属性调用设置器是没有意义的。我怀疑他们是否想引入蠕虫病毒,因为它可能是模棱两可的,因此可以直接在初始化程序之外的任何地方直接设置备份字段的值。
像这样的代表应该足够。如果不足以帮助您立即解决多次调用setter的错误,我想说这是一种代码味道,说明该类太复杂了,需要分解成较小的单元。
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.")
}
}
}