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.")
}
}
}
我知道在 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.")
}
}
}