【问题标题】:Why is the closure called when using HashMap's or_insert?为什么在使用HashMap的or_insert时会调用闭包?
【发布时间】:2018-07-02 10:04:08
【问题描述】:

我从 Rust 开始,很难理解下面的 sn-p 代码如何输出它的作用。当条目存在时,or_insert 方法中的闭包肯定不应该被调用,还是我完全遗漏了什么?

struct Cacher {
    result: HashMap<u32, u32>,
}

impl Cacher {
    fn new() -> Cacher {
        Cacher{
            result: HashMap::new()
        }
    }

    fn result(&mut self, arg: u32) -> u32 {
        match self.result.get(&arg) {
            Some(v) => println!("I have value {} for {}", v, arg),
            None => println!("No value for {}", arg)
        }
        let closure = |x| {
            println!("Doing complicated stuff.....");
            thread::sleep(Duration::from_secs(2));
            x + 42
        };
        let v = self.result.entry(arg).or_insert((closure)(arg));
        *v
    }
}

fn main() {
    let mut business_logic = Cacher::new();
    business_logic.result(10);
    business_logic.result(10);
}

输出:

No value for 10
Doing complicated stuff.....
I have value 52 for 10
Doing complicated stuff.....

【问题讨论】:

    标签: hashmap rust


    【解决方案1】:

    闭包之所以叫是因为你叫它

    (closure)(arg)
    

    hash_map::Entry::or_insert 不接受闭包:

    pub fn or_insert(self, default: V) -> &'a mut V
    

    通过插入默认值(如果为空)来确保值在条目中,并且 返回对条目中值的可变引用。

    hash_map::Entry::or_insert_with 会:

    pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V
    

    通过插入默认值的结果来确保条目中存在一个值 函数如果为空,则返回对中值的可变引用 进入。

    应用于您的代码:

    fn result(&mut self, arg: u32) -> u32 {
        match self.result.get(&arg) {
            Some(v) => println!("I have value {} for {}", v, arg),
            None => println!("No value for {}", arg),
        }
        *self.result.entry(arg).or_insert_with(|| {
            println!("Doing complicated stuff.....");
            thread::sleep(Duration::from_secs(2));
            arg + 42
        })
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-14
      • 1970-01-01
      • 1970-01-01
      • 2019-05-07
      • 1970-01-01
      • 2014-09-21
      • 2010-09-20
      • 1970-01-01
      相关资源
      最近更新 更多