Kotlin 实现具有更新能力的惰性变量的最佳方法

问题描述

通过延迟初始化、私有 setter 和使用昂贵方法更改值的能力来实现变量的最佳方法是什么?

我的意思是这样的:

private const val NO_INIT = "noInit"

class LazyUpdatableVarClass {
    private val initValue by lazy { expensive() }
    var value = NO_INIT
        private set
        get() {
            if (field == NO_INIT) {
                field = initValue
            }
            return field
        }

    fun updateValue() {
        value += expensive()
    }

    private fun expensive() = "hello"
}

这是最短和最好的方法吗?我认为自定义委托并不短,因为我需要一个实现。或者也许有图书馆代表?

用法示例:

val example = LazyUpdatableVarClass()
assertEquals("hello",example.value)
example.updateValue()
assertEquals("hellohello",example.value)

解决方法

可变 pdf("plot1.pdf") repeat { ID = ID + 1 print(ggplot(ID)) if (ID == 72){ break}} dev.off() 的自定义委托对您无济于事,因为您不能拥有带有委托的私有 setter(或任何自定义 setter/getter)。

实现此 API 的更简洁的方法是将 value 声明为 value 并使用可变的 backing property (val):

_value
,

假设您没有使其成为线程安全的,因为您的示例代码不是,那么使用可为空的支持属性并省略冗余的 Lazy 委托会更简洁且开销更少。

class LazyUpdatableVarClass {
    private var _value: String? = null
    var value: String
        private set(x) { _value = x }
        get() = _value ?: expensive().also { _value = it }

    fun updateValue() {
        value += expensive()
    }

    private fun expensive() = "hello"
}

您也可以考虑将其设置为 val 并专门通过 backing 属性对其进行修改,但这需要更改此类的其他方法:

class LazyUpdatableVarClass {
    private var _value: String? = null
    val value: String
        get() = _value ?: expensive().also { _value = it }

    fun updateValue() {
        _value = value + expensive()
    }

    private fun expensive() = "hello"
}