【发布时间】:2021-07-14 05:12:34
【问题描述】:
寻找一种自然的 Kotlin 方式,让 startTime 仅在特定位置初始化一次。
下面的幼稚实现有两个问题:
- 它不是线程安全的
- 它没有表示“变量在 Item 实例的生命周期中被或将被分配一次”
class Item {
var startTime: Instant?
fun start(){
if (startTime == null){
startTime = Instant.now()
}
// do stuff
}
}
我相信某种类型的委托可能适用于此。换句话说,这段代码需要类似于lazy 变量的东西,但在第一次读取时没有初始化,而是仅在显式调用“touching”方法后发生。也许Wrap 调用可以提供可能实现的想法。
class Wrap<T>(
supp: () -> T
){
private var value: T? = null
private val lock = ReentrantLock()
fun get(){
return value
}
fun touch(){
lock.lock()
try{
if (value == null){
value = supp()
} else {
throw IllegalStateExecption("Duplicate init")
}
} finally{
lock.unlock()
}
}
}
【问题讨论】:
-
我不明白为什么
lazy()不适合您的情况。如果您的“接触”方法只是在惰性值上调用 read 来初始化它怎么办?当有人在调用“触摸”方法之前尝试读取值时,您的预期行为是什么? -
@broot 值有一个初始状态(即
null),阅读器在“触摸”之前读取值时会得到它 -
我完全重写了我的答案以满足仅从
start()方法设置值的要求。
标签: kotlin design-patterns delegates lazy-evaluation