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

如何限制在Rust中借用值的范围?,rust,borrow-checker,Rust,Borrow Checker,我正试着在《铁锈》里写些回忆录,我和借书人发生了冲突 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

我正试着在《铁锈》里写些回忆录,我和借书人发生了冲突

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
    }
}
fn计算deps(缓存:&mut HashMap,键:&String)->String{
如果let Some(v)=cache.get(key){
v
}否则{
设r=/*计算*/
cache.insert(key.clone(),r.clone());
R
}
}

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

问题在于
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
    }
}
您也可以简单地使用
或_insert
而不是
或_insert_with
,但这需要无条件地对
r
进行计算

pub fn calc_deps(cache: &mut HashMap<String, String>, key: String) -> String {
    cache
        .entry(key)
        .or_insert(String::from("computations"))
        .clone()
}
pub fn calc_deps(缓存:&mut HashMap,键:String)->String{
隐藏物
.入口(钥匙)
.或_insert(字符串::from(“计算”))
.clone()
}

问题在于
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
    }
}
您也可以简单地使用
或_insert
而不是
或_insert_with
,但这需要无条件地对
r
进行计算

pub fn calc_deps(cache: &mut HashMap<String, String>, key: String) -> String {
    cache
        .entry(key)
        .or_insert(String::from("computations"))
        .clone()
}
pub fn calc_deps(缓存:&mut HashMap,键:String)->String{
隐藏物
.入口(钥匙)
.或_insert(字符串::from(“计算”))
.clone()
}

如果是我的话,它会在夜间使用
#编译![功能(nll)]
。另请参见切题相关:如果是我,它会在夜间使用
#编译![功能(nll)]
。另请参见切题:我喜欢这些解决方案。如果我想坚持最初的想法,基本上实现您在这里向我们展示的功能,该怎么办?我不应该写这样的东西:`{let x;{x=cache.get(key.clone()};if let Some(v)=x吗{…``为什么不行?@simon1505475:因为当你克隆一个
选项
时,你仍然有一个
选项
。这就是为什么我用
映射
取出引用,然后克隆它,因为对引用调用
克隆
会克隆引用的对象。然而,我刚刚了解了的另一个函数de>选项与我使用
映射所做的一样
如果让Some(v)=cache.get(key).cloned(){…
(并不是说它是
克隆的
,而是
克隆的
)我将更新我的答案以反映它。我喜欢这些解决方案。如果我想坚持最初的想法,基本上实现您在这里向我们展示的函数,该怎么办?我难道不能编写类似这样的内容:```{let x;{x=cache.get(key.clone()};if let Some(v)=x吗{…``为什么不行?@simon1505475:因为当你克隆一个
选项
时,你仍然有一个
选项
。这就是为什么我用
映射
取出引用,然后克隆它,因为对引用调用
克隆
会克隆引用的对象。然而,我刚刚了解了的另一个函数de>选项与我使用
映射所做的一样
如果让Some(v)=cache.get(key).cloned(){…
(不是它是
克隆的
,而是
克隆的
),我将更新我的答案以反映它。