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查找只发生一次。太好了,谢谢!