Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 我如何说服借阅检查器允许我缓存值?_Rust_Borrow Checker - Fatal编程技术网

Rust 我如何说服借阅检查器允许我缓存值?

Rust 我如何说服借阅检查器允许我缓存值?,rust,borrow-checker,Rust,Borrow Checker,借债人打败了我: 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];

借债人打败了我:

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;
            }
        }
    }
}

如何重写代码以使其编译?

借用检查器将
缓存。get
视为不可变借用,尽管它返回
None
。更改代码的最简单方法是将插入项移出匹配项,例如:

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;
    }
}
使用std::collections::HashMap;
结构缓存{
缓存:Vec,
}
impl缓存{
fn get(&mut self,索引:usize,键:String)->String{
让mut cache=&mut self.cache[index];
匹配缓存。获取(&key){
一些(r)=>{
返回r.clone();
}
无=>(),
}
让r=“foo”。to_string();//这里有一些聪明的东西
cache.insert(key,r.clone());
返回r;
}
}

另一种方法是使用
条目
界面。这种方法唯一的缺点是(目前)没有使用
get
方法使用的
借用
基础结构,这使得它的灵活性降低。在您的情况下,这不是问题,因为
get
接受一个拥有的密钥。
entry
的优点是它只执行一次哈希查找,而使用
get
强制执行两次查找

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()
    }
}
使用std::collections::HashMap;
结构缓存{
缓存:Vec,
}
impl缓存{
fn get(&mut self,索引:usize,键:String)->String{
self.cache[索引]
.入口(钥匙)
.或插入带(| | foo.to_string())
.clone()
}
}

我认为拥有近6k代表的人会将他们的问题编排得更好一些。“如何重写代码以使其编译”并没有真正针对您的特定问题(不理解为什么不能将字段借用为可变字段,而将其借用为不可变字段)。签出,向下滚动到“借用范围不应总是词汇化的”,然后向上阅读。它解释了发生此错误的原因,以及如何避免此错误也可以提供一些见解。“您必须克隆密钥”是否确定?我不明白为什么不能把钥匙移到
entry()
调用中。@VladimirMatveev你说得绝对正确。我的意思是说
entry
没有
get
那样灵活的界面。我已经更新了我的答案。据我所知,我还应该将借用基础结构添加到
条目中。@BurntSushi5我非常喜欢你的决定,因为HashMap查找只发生一次。太好了,谢谢!