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

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

class Foo(val base : FooBase){ var _number: Int? = null override var number: Int get() = _number ?: base.number set(value) {_number = value} } 

不过,我有很多像这样的属性,导致了很多代码的重复。 有没有办法避免这种情况? 我明白财产代表团是这样做的一种方式,但我不确定如何正确实施ReadWriteProperty<...> 。 如果我应该使用它,我该如何使用“财产”价值?

这是一个比Yoav Sternberg的回答更好的表现。 正如你所看到的,它不是通用的,但它可以避免整数的自动装箱:

 class IntUninitializedProperty(private val getter: () -> Int) { private var isInitialised = false private var value: Int = 0 fun getValue(thisRef: Any?, property: KProperty<*>): Int = if(isInitialised) value else getter() fun setValue(thisRef: Any?, property: KProperty<*>, value: Int) { this.value = value isInitialised = true } } 

您需要创建一个扩展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 } 

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

 fun <T> uninitialized(getter: () -> T): ReadWriteProperty<Any?, T> = UninitializedProperty(getter) 

现在你可以使用它:

 class Foo(val base: FooBase) { override var number: Int by uninitialized { base.number } } 

注意:这个类不是线程安全的。

查看官方文档以获取有关委派的更多信息。