繁体   English   中英

Rust Cahcer 与 HashMap 第 13 章

[英]Rust Cahcer with HashMap Chapter 13

正如第 13 章所建议的,我正在尝试使用 HashMap 来实现缓存器。 与其他一些问题不同,我试图遵循作者采用的方法,并在缓存中使用 Option 作为值。

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));

运行它时我会感到恐慌。 线程 'main' 在 '调用Option::unwrap() on a None value' 时惊慌失措 有什么建议么? 为什么 unwrap 这里是 None ? 非常感谢

let mut map = HashMap::new(); let v = map.insert(arg, (self.calc)(arg)).unwrap(); self.value = Some(map); v

我认为您对HashMap::insert返回的内容感到困惑:它返回键的先前值(如果有)(这就是为什么它是Option )。

因此,当您刚刚创建了一个空的 map 并且您第一次插入其中时...它返回None因为那里不可能存在现有值。 因此,此代码路径只能恐慌。

顺便说一句,由于完全不必要Option<HashMap> ,代码过于复杂:

hash map 最初创建时容量为 0,因此在第一次插入之前不会分配。

因此,抛开这将作为时间优化发挥任何作用的想法不谈,它甚至没有这样做,因为分配被延迟到第一次插入。

在两个代码路径上还有一个问题: Rust 是一种急切的语言,这意味着:

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);

所以即使它已经在缓存中,你也可以运行计算,而不是用 memory 换 CPU,这个实现只会浪费 memory。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM