rust - 带 HashMap 的缓存器
问题描述
按照第 13.1 章的建议,我尝试使用 HashMap 实现缓存器:
use std::collections::HashMap;
pub struct Cacher<T, U>
where
T: Fn(U) -> U,
U: std::cmp::Eq + std::hash::Hash + Copy,
{
calculation: T,
values: HashMap<U, U>,
}
impl<T, U> Cacher<T, U>
where
T: Fn(U) -> U,
U: std::cmp::Eq + std::hash::Hash + Copy,
{
pub fn new(calculation: T) -> Cacher<T, U> {
Cacher {
calculation,
values: HashMap::new(),
}
}
pub fn value(&mut self, arg: U) -> &U{
self.values.entry(arg).or_insert((self.calculation)(arg))
}
}
但运行以下代码:
use cacher::Cacher;
fn main() {
let mut cacher = Cacher::new(|arg|{
println!("Executing for {:?}", arg);
arg
});
assert_eq!(cacher.value(1), &1);
assert_eq!(cacher.value(2), &2);
assert_eq!(cacher.value(3), &3);
assert_eq!(cacher.value(1), &1);
assert_eq!(cacher.value(2), &2);
}
产生以下输出:
Compiling cacher v0.1.0 (C:\Users\felix\Programming\rust\projects\Cacher)
Finished dev [unoptimized + debuginfo] target(s) in 0.67s
Running `target\debug\cacher.exe`
Executing for 1
Executing for 2
Executing for 3
Executing for 1
Executing for 2
显示缓存器不起作用,对每个值调用执行计算,即使是已知参数。价值函数出了什么问题
解决方案
即使密钥已经存在,看起来也正在调用该函数。
与以下代码fn value(&mut self, arg: U)
相同的代码:
pub fn value(&mut self, arg: U) -> &U {
let placeholder = (self.calculation)(arg);
self.values.entry(arg).or_insert(placeholder)
}
因此,您可以改为使用 method .or_insert_with()
,它允许您传递一个仅在密钥不存在时才调用的函数,如评论中发布的操场所示:
pub fn value(&mut self, arg: U) -> &U {
let calculation = &self.calculation;
self.values.entry(arg).or_insert_with(|| calculation(arg))
}
推荐阅读
- javascript - 消息组件超级慢
- python - 同时对两列进行自定义排序 Pandas
- python - 为什么 Python 的时间函数(如 perf_counter_ns)的解析会出现不一致?
- qt - 如何在不删除文本的情况下在网格中显示 QListWidgetItems?
- java - 如何使用 PowerMockito 模拟私有方法?
- reactjs - 如何将我的 API URL 代理到其他代理
- angular - 自定义异步验证器,用于验证来自后端 api 的电子邮件,称为在页面加载时多次调用
- arrays - 如何将 R 中的向量对象插入到双精度 [] 类型的 PostgreSQL 列中,该列是一个浮点数组
- android - 当我尝试使用 FusedLocationProviderClient 时出现错误
- tensorflow - ValueError:一个操作对梯度有“无”。在 Keras 中实现自定义损失函数时