正如第13章所建议的,我正在尝试用一个HashMap来实现Cacher。与其他问题不同的是,我试图遵循作者的观点,并在“传道者”中使用选项作为价值。
struct Cacher<T>
where T: Fn(u32) -> u32, //struct needs to know Type of closure(aka calc)
{
calc: T,
value: Option<HashMap<u32, u32>>
}
impl<T> Cacher<T>
where T: Fn(u32) -> u32,{
fn new(calculation: T) -> Cacher<T>{
Cacher {
calc: calculation,
value: None
}
}
fn value(&mut self, arg: u32) -> u32 {
match &mut self.value {
Some(map) => {
let v = map.entry(arg).or_insert((self.calc)(arg));
*v
},
None => {
let mut map = HashMap::new();
let v = map.insert(arg, (self.calc)(arg)).unwrap();
self.value = Some(map);
v
}
}
}
}代码编译,但甚至运行一个简单的:
let mut expensive_res = Cacher::new( |num| {
println!("calculating slowly....{}", num);
thread::sleep(Duration::from_secs(1));
num + 100
});
println!("{}", expensive_res.value(1));我在运行它的时候会感到恐慌。一个名为“Option::unwrap() None on Nonevalue”的线程“main”惊慌失措了。有什么建议吗?为什么在这里拆开是一个零?非常感谢
发布于 2022-01-27 13:07:03
让map = HashMap::new();让v= map.insert(arg,(self.calc)(arg)).unwrap();self.value = Some(map);v
我认为您对HashMap::insert返回的内容感到困惑:它返回键的前一个值(如果有的话)(这就是为什么它是一个Option)。
所以,当你刚刚创建了一个空的地图,你第一次插入它.它返回None,因为那里不可能有一个现有的值。因此,这段代码只能引起恐慌。
顺便说一句,由于完全不必要的Option<HashMap>,代码太复杂了。
--哈希映射最初是以0的容量创建的,因此它在第一次插入之前不会分配。
因此,抛开这将作为一种时间优化的任何作用的想法,它甚至没有这样做,因为分配会被推迟到第一次插入。
这两种代码都有另外一个问题:锈病是一种热切的语言,意思是:
let v = map.entry(arg).or_insert((self.calc)(arg));相当于:
let mut entry = map.entry(arg);
let default = (self.calc)(arg);
let v = entry.or_insert(default);所以您正在运行计算,即使它已经在缓存中,也不是用内存来交换CPU --这个实现只是浪费内存。
https://stackoverflow.com/questions/70878929
复制相似问题