How can I convince the borrow checker to allow me to cache values?

走远了吗. 提交于 2019-12-01 21:40:59
BurntSushi5

Another approach is to use the entry interface. The only downside with this approach is that it (currently) doesn't use the BorrowFrom infrastructure that the get method uses, which makes it less flexible. In your case, that isn't a problem since get takes an owned key. The advantage of entry is that it only does one hash lookup, whereas using get forces you to do two lookups.

use std::collections::HashMap;

struct Cache {
    cache: Vec<HashMap<String, String>>,
}

impl Cache {
    fn get(&mut self, index: usize, key: String) -> String {
        self.cache[index]
            .entry(key)
            .or_insert_with(|| "foo".to_string())
            .clone()
    }
}
Greg Oschwald

The borrow checker sees cache.get as an immutable borrow, despite the fact that it is returning None. The easiest way to change your code is to move the insert out of the match, e.g.:

use std::collections::HashMap;

struct Cache {
    cache: Vec<HashMap<String, String>>,
}

impl Cache {
    fn get(&mut self, index: usize, key: String) -> String {
        let mut cache = &mut self.cache[index];
        match cache.get(&key) {
            Some(r) => {
                return r.clone();
            }
            None => (),
        }
        let r = "foo".to_string(); // something smart here
        cache.insert(key, r.clone());
        return r;
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!