Rust 如何限制借用值的范围?

How to limit the scope in which a value is borrowed in Rust?

我正在尝试用 Rust 做一些记忆,我 运行 与借用检查器有冲突。

fn calc_deps(cache: &mut HashMap<String, String>, key: &String) -> String {
    if let Some(v) = cache.get(key) {
        v
    } else {
        let r = /* computations */
        cache.insert(key.clone(),r.clone());
        r
    }
}

我听说缓存被借用了两次。如果我在插入时完成了获取,为什么会出现问题?我有办法对这些信息进行编码吗?

问题是 v 的生命周期适用于整个 if/else 块,即使它在 else 部分不可用。您可以在 Option::cloned.

的帮助下解决这个问题
pub fn calc_deps(cache: &mut HashMap<String, String>, key: &String) -> String {
    if let Some(v) = cache.get(key).cloned() {
        v
    } else {
        let r = String::from("computations");
        cache.insert(key.clone(), r.clone());
        r
    }
}

Option::cloned 通过克隆内容将 Option<&T> 映射到 Option<T>。所以现在 v 变成了 String 而不是 &String,并且不再借用 cache.

另一种选择是使用HashMap::entry/or_insert_with 界面。它可能更惯用,但它需要无条件地克隆 key.

pub fn calc_deps(cache: &mut HashMap<String, String>, key: String) -> String {
    cache
        .entry(key)
        .or_insert_with(|| String::from("computations"))
        .clone()
}

您也可以简单地使用 or_insert 而不是 or_insert_with,但这需要无条件地对 r 进行计算。

pub fn calc_deps(cache: &mut HashMap<String, String>, key: String) -> String {
    cache
        .entry(key)
        .or_insert(String::from("computations"))
        .clone()
}