rust 是否从条目中取回HashMap?[duplicate]

rbl8hiat  于 2022-11-24  发布在  其他
关注(0)|答案(1)|浏览(114)

此问题在此处已有答案

Returning a reference from a HashMap or Vec causes a borrow to last beyond the scope it's in?(1个答案)
昨天关门了。
我实现了一个缓存,它尝试在表中查找,如果失败,它尝试一个简单的方法来获取值,如果失败,它会该高速缓存中计算 * 多个 * 新条目。Entry系统似乎是专门为前半部分设计的,但我无法让借位检查器允许我完成后半部分。

use std::collections::HashMap;
fn main() {
    let mut cache = Cache { cache: HashMap::new() };
    println!("{}", cache.get_from_cache(10));

}

struct Cache {
    cache: HashMap<u32, String>
}
impl Cache {
    fn get_from_cache<'a>(&'a mut self, i: u32) -> &'a String {
        match self.cache.entry(i) {
            std::collections::hash_map::Entry::Occupied(entry) => return entry.into_mut(),
            std::collections::hash_map::Entry::Vacant(entry) => {
                // Some values have an easy way to be computed...
                if i == 5 {
                    return entry.insert("my string".to_string())
                }
            }
        }

        // Neither look-up method succeeded, so we 'compute' values one-by-one
        for j in 1..=i {
            self.cache.insert(j, "another string".to_string()); // Borrow checker fails here
        }
        self.cache.get(&i).unwrap()
        
    }
    
}

问题是Entryself.cache.entry(i)借用了self.cache的整个生命周期'a,即使我在尝试执行self.cache.insert时不再需要它。
一个解决方法是将对Entry的引用转换为对HashMap的引用,然后通过该引用插入。但是,我看不出有什么方法可以通过entry接口实现这一点。有什么方法可以实现这一点吗?或者满足借位检查器?

nxagd54h

nxagd54h1#

通过将插入值与返回最终结果分开,可以很容易地解决这个问题。您可以首先确保值在该高速缓存中,如果没有,则使用某种策略插入它,然后返回新值(现在保证在HashMap中):

fn get_from_cache<'a>(&'a mut self, i: u32) -> &'a String {
    // handle inserting the value if necessary:
    match self.cache.entry(i) {
        std::collections::hash_map::Entry::Occupied(entry) => (),
        // Some values have an easy way to be computed...
        std::collections::hash_map::Entry::Vacant(entry) if i == 5 => {
            entry.insert("my string".to_string());
        }
        // ... others aren't
        std::collections::hash_map::Entry::Vacant(entry) => {
            for j in 1..=i {
                self.cache.insert(j, "another string".to_string());
            }
        }
    }

    // The value is now definitely in `self.cache` so we can return a reference to it
    &self.cache[&i]
    
}

相关问题