【发布时间】:2017-10-31 21:29:30
【问题描述】:
我的系统中有事件和一个根据事件和最后计算值计算值的函数:
当我调用这个函数时,我想要这种行为:
- 如果有新的事件,它应该使用事件和最后记忆的值计算新值,并记忆结果
- 如果没有新事件,它应该返回最后一个被记忆的值
这是我想出的实现:
<!-- language: lang-scala -->
class EventBasedMemo[Value, Event](initialValue: => Value,
buildValue: (Value, Event) => Value,
nextEvent: Option[Event] = None) {
lazy val memoValue: Value =
nextEvent.fold(initialValue)(event => buildValue(initialValue, event))
def update(event: Event): EventBasedMemo[Value, Event] =
new EventBasedMemo(memoValue, buildValue, Option(event))
}
type Value = Int
type Event = String
var callsCount = 0
var memo = new EventBasedMemo[Value, Event](0, (value, event) => {
callsCount += 1
println(s"$callsCount $event")
value + 1
})
memo = memo.update("A")
memo = memo.update("B")
memo = memo.update("C")
memo.memoValue // 1 A 2 B 3 C
memo.memoValue
memo = memo.update("D")
memo.memoValue // 4 D
这很好用。但问题是lazy val 在后台使用同步,因此计算时会发生多个嵌套同步,这很糟糕。
如何更改它以使其仅使用一次同步?
我希望解决方案是不可变的。
【问题讨论】:
标签: scala synchronization lazy-evaluation memoization