Kotlin 实现具有更新能力的惰性变量的最佳方式
Kotlin best way to implement lazy var with ability to update
实现具有惰性初始化、私有 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)
可变 value
的自定义委托对您没有帮助,因为您不能拥有私有 setter(或任何自定义 setter/getter)与委托。
实现此 API 的更简洁的方法是将 value
声明为 val
并使用可变的 backing property (_value
):
class LazyUpdatableVarClass {
private lateinit var _value: String
private fun getValueOrInit(): String {
if (!::_value.isInitialized) _value = expensive()
return _value
}
fun updateValue() {
_value = getValueOrInit() + expensive()
}
val value get() = getValueOrInit()
private fun expensive() = "hello"
}
假设您没有使其成为线程安全的,因为您的示例代码不是,使用可空支持 属性 并省略冗余的 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
并通过支持 属性 专门对其进行修改,但这需要更改此 class 的其他方法:
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"
}
实现具有惰性初始化、私有 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)
可变 value
的自定义委托对您没有帮助,因为您不能拥有私有 setter(或任何自定义 setter/getter)与委托。
实现此 API 的更简洁的方法是将 value
声明为 val
并使用可变的 backing property (_value
):
class LazyUpdatableVarClass {
private lateinit var _value: String
private fun getValueOrInit(): String {
if (!::_value.isInitialized) _value = expensive()
return _value
}
fun updateValue() {
_value = getValueOrInit() + expensive()
}
val value get() = getValueOrInit()
private fun expensive() = "hello"
}
假设您没有使其成为线程安全的,因为您的示例代码不是,使用可空支持 属性 并省略冗余的 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
并通过支持 属性 专门对其进行修改,但这需要更改此 class 的其他方法:
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"
}