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

Properties 如何实现从某个源提取的属性,直到它直接在Kotlin中设置为止?,properties,kotlin,Properties,Kotlin,我目前有一个财产声明如下: class Foo(val base : FooBase){ var _number: Int? = null override var number: Int get() = _number ?: base.number set(value) {_number = value} } 然而,我有很多这样的属性,导致了相当多的代码重复。有没有办法避免这种情况?我知道属性委托是实现这一点的一种方法,但我不确定如何正确实现

我目前有一个财产声明如下:

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

    override var number: Int
        get() = _number ?: base.number
        set(value) {_number = value}
}

然而,我有很多这样的属性,导致了相当多的代码重复。有没有办法避免这种情况?我知道属性委托是实现这一点的一种方法,但我不确定如何正确实现
ReadWriteProperty
。如果我应该使用“property”值,我该如何使用它?

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

现在您可以使用它:

class Foo(val base: FooBase) {
    override var number: Int by uninitialized { base.number }
}
注意:该类不是线程安全的


查看以了解有关委派的更多信息。

与Yoav Sternberg的答案相比,这里有一个性能改进。如您所见,它不太通用,但它避免了int的自动装箱:

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
    }
}
类IntUninitializedProperty(私有val getter:()->Int){
私有var已初始化=false
私有变量值:Int=0
fun getValue(thisRef:Any?,属性:KProperty):Int=if(IsInitialized)value else getter()
fun setValue(thisRef:Any?,属性:KProperty,值:Int){
this.value=value
IsInitialized=true
}
}

我建议将
私有对象未初始化\u值
放在
未初始化属性
中,而不是放在它旁边。实现有一个bug。如果它被初始化为
null
?要修复它,您需要将
\u值
未初始化的\u值
进行比较,而不是与
null
进行比较。
class Foo(val base: FooBase) {
    override var number: Int by uninitialized { base.number }
}
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
    }
}