Kotlin是实现具有更新功能的惰性var的最佳方法

Kotlin是实现具有更新功能的惰性var的最佳方法,kotlin,delegates,lazy-initialization,Kotlin,Delegates,Lazy Initialization,使用惰性初始化、私有setter和使用昂贵方法更改值的能力实现变量的最佳方法是什么 我的意思是这样的: private const val NO_INIT = "noInit" class LazyUpdatableVarClass { private val initValue by lazy { expensive() } var value = NO_INIT private set get() {

使用惰性初始化、私有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)

可变
值的自定义委托对您没有帮助,因为您不能将私有setter(或任何自定义setter/getter)与委托一起使用

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"
}
实现此API的更简洁的方法是将
value
声明为
val
,并使用可变(
\u value
):

class LazyUpdateableVarClass{
私有lateinit var_值:字符串
private fun getValueOrInit():字符串{
如果(!::_value.isInitialized)_value=昂贵()
返回值
}
fun updateValue(){
_value=getValueOrInit()+昂贵()
}
val value get()=getValueOrInit()
private fun昂贵()=“你好”
}

可变
值的自定义委托对您没有帮助,因为您不能将私有setter(或任何自定义setter/getter)与委托一起使用

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"
}
实现此API的更简洁的方法是将
value
声明为
val
,并使用可变(
\u value
):

class LazyUpdateableVarClass{
私有lateinit var_值:字符串
private fun getValueOrInit():字符串{
如果(!::_value.isInitialized)_value=昂贵()
返回值
}
fun updateValue(){
_value=getValueOrInit()+昂贵()
}
val value get()=getValueOrInit()
private fun昂贵()=“你好”
}

假设由于示例代码不是线程安全的,所以您没有使其成为线程安全的,那么使用可为空的备份属性并省略冗余的延迟委托将更简洁,开销也更小

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"
}

您也可以考虑将其定义为<代码> Valu/COD>并通过Buffic属性专门修改它,但这需要对该类的其他方法进行更改:

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"
}

假设由于示例代码不是线程安全的,所以没有使其成为线程安全的,那么使用可为null的backing属性并省略冗余的惰性委托将更简洁,开销更小

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"
}

您也可以考虑将其定义为<代码> Valu/COD>并通过Buffic属性专门修改它,但这需要对该类的其他方法进行更改:

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"
}

我喜欢第二个选项,它只有3行!我喜欢第二个选项,它只有3行!