为什么在使用HashMap的or_insert时会调用闭包?

时间:2018-01-23 14:33:48

标签: hashmap rust

我开始使用Rust,并且无法理解下面的代码片段如何输出它的作用。当条目存在或我完全遗漏某些内容时,不应该调用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.....

1 个答案:

答案 0 :(得分:3)

闭包被称为因为你调用它

(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
    })
}