如何实现从某个源获取的属性,直到它直接在Kotlin中设置?

use*_*024 2 properties kotlin

我目前有一个声明如下的属性:

class Foo(val base : FooBase){
    var _number: Int? = null

    override var number: Int
        get() = _number ?: base.number
        set(value) {_number = value}
}
Run Code Online (Sandbox Code Playgroud)

但是,我有很多这样的属性,导致相当多的代码重复.有办法避免这种情况吗?我知道属性委托是一种方法,但我不确定如何ReadWriteProperty<...>正确实现.如果我应该使用它,我如何使用"属性"值?

Yoa*_*erg 6

您需要创建一个扩展的类来ReadWriteProperty提供功能(代码示例基于不安全的延迟实现)

class UninitializedProperty<T>(private val getter: () -> T) : ReadWriteProperty<Any?, T> {
    var _value: Any? = UNINITIALIZED_VALUE

    @Suppress("UNCHECKED_CAST")
    override fun getValue(thisRef: Any?, property: KProperty<*>): T = if(_value === UNINITIALIZED_VALUE) getter() else _value as T

    override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
        _value = value
    }

   private object UNINITIALIZED_VALUE
}
Run Code Online (Sandbox Code Playgroud)

接下来,定义一个辅助方法,以便与标准委托保持一致lazy:

fun <T> uninitialized(getter: () -> T): ReadWriteProperty<Any?, T> = UninitializedProperty(getter)
Run Code Online (Sandbox Code Playgroud)

现在你可以使用它:

class Foo(val base: FooBase) {
    override var number: Int by uninitialized { base.number }
}
Run Code Online (Sandbox Code Playgroud)

注意:该类不是线程安全的.

有关委派的更多信息,请查看官方文档.