【问题标题】:Cacher with HashMap带 HashMap 的缓存器
【发布时间】:2021-08-29 20:47:56
【问题描述】:

按照第 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

显示缓存器不起作用,为每次调用 value 执行计算,即使是已知的 args。 价值函数出了什么问题

【问题讨论】:

标签: rust


【解决方案1】:

看起来函数正在被调用,即使键已经存在。

fn value(&amp;mut self, arg: U) 的代码与下面的代码相同:

pub fn value(&mut self, arg: U) -> &U {
    let placeholder = (self.calculation)(arg);
    self.values.entry(arg).or_insert(placeholder)
}

因此,您可以改用.or_insert_with() 方法,它允许您传递一个仅在密钥不存在时才调用的函数,如the playground posted in the comments 所示:

pub fn value(&mut self, arg: U) -> &U {
    let calculation = &self.calculation;
    self.values.entry(arg).or_insert_with(|| calculation(arg))
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-23
    • 1970-01-01
    • 1970-01-01
    • 2019-07-27
    • 2019-02-20
    • 1970-01-01
    相关资源
    最近更新 更多