几天前,我遇到了使用scala的回调和代理模式实现。 如果值不在地图中,则此代码应仅应用内部函数。 但是每次地图重新初始化并且价值观都消失了(这看起来很顺利。
如何在不同的函数调用之间反复使用相同的缓存
class Aggregator{
def memoize(function: Function[Int, Int] ):Function[Int,Int] = {
val cache = HashMap[Int, Int]()
(t:Int) => {
if (!cache.contains(t)) {
println("Evaluating..."+t)
val r = function.apply(t);
cache.put(t,r)
r
}
else
{
cache.get(t).get;
}
}
}
def memoizedDoubler = memoize( (key:Int) => {
println("Evaluating...")
key*2
})
}
object Aggregator {
def main( args: Array[String] ) {
val agg = new Aggregator()
agg.memoizedDoubler(2)
agg.memoizedDoubler(2)// It should not evaluate again but does
agg.memoizedDoubler(3)
agg.memoizedDoubler(3)// It should not evaluate again but does
}
答案 0 :(得分:1)
您是不是每次调用都声明一个新的Map
?
def memoize(function: Function[Int, Int] ):Function[Int,Int] = {
val cache = HashMap[Int, Int]()
而不是指定{em>每个实例一个 Aggregator
?
e.g。
class Aggregator{
private val cache = HashMap[Int, Int]()
def memoize(function: Function[Int, Int] ):Function[Int,Int] = {
答案 1 :(得分:1)
我看到你在这里尝试做什么,它不起作用的原因是每次你打电话memoizedDoubler
它首先打电话memorize
。如果您希望memoizedDoubler
只调用val
一次,则需要将def
声明为memoize
而不是 val memoizedDoubler = memoize( (key:Int) => {
println("Evaluating...")
key*2
})
。
def
这个答案很好地解释了val
和ID 2
之间的区别。 https://stackoverflow.com/a/12856386/37309
答案 2 :(得分:0)
回答你的问题:
如何使用函数式编程实现缓存
在函数式编程中,没有可变状态的概念。如果要更改某些内容(如缓存),则需要返回更新的缓存实例以及结果,并将其用于下一次调用。
以下是修改遵循该方法的代码。 function
计算值,cache
合并到Aggregator
。调用memoize
时,它将返回元组,其中包含计算结果(可能来自缓存)和新Aggregator
应该用于下一次调用。
class Aggregator(function: Function[Int, Int], cache:Map[Int, Int] = Map.empty) {
def memoize:Int => (Int, Aggregator) = {
t:Int =>
cache.get(t).map {
res =>
(res, Aggregator.this)
}.getOrElse {
val res = function(t)
(res, new Aggregator(function, cache + (t -> res)))
}
}
}
object Aggregator {
def memoizedDoubler = new Aggregator((key:Int) => {
println("Evaluating..." + key)
key*2
})
def main(args: Array[String]) {
val (res, doubler1) = memoizedDoubler.memoize(2)
val (res1, doubler2) = doubler1.memoize(2)
val (res2, doubler3) = doubler2.memoize(3)
val (res3, doubler4) = doubler3.memoize(3)
}
}
打印:
Evaluating...2
Evaluating...3