我想同时从哈希图中获取两个值,但我无法逃避以下错误,我已将代码简化如下,任何人都可以帮助我修复此错误。
#[warn(unused_variables)]
use hashbrown::HashMap;
fn do_cal(a: &[usize], b: &[usize]) -> usize {
a.iter().sum::<usize>() + b.iter().sum::<usize>()
}
fn do_check(i: usize, j:usize) -> bool {
i/2 < j - 10
}
fn do_expensive_cal(i: usize) -> Vec<usize> {
vec![i,i,i]
}
fn main() {
let size = 1000000;
let mut hash: HashMap<usize, Vec<usize>> = HashMap::new();
for i in 0..size{
if i > 0 {
hash.remove(&(i - 1));
}
if !hash.contains_key(&i){
hash.insert(i, do_expensive_cal(i));
}
let data1 = hash.get(&i).unwrap();
for j in i + 1..size {
if do_check(i, j) {
break
}
if !hash.contains_key(&j){
hash.insert(j, do_expensive_cal(j));
}
let data2 = hash.get(&j).unwrap();
let res = do_cal(data1, data2);
println!("res:{}", res);
}
}
}
Run Code Online (Sandbox Code Playgroud)
错误[E0502]:无法hash作为可变借用,因为它也作为不可变借用
--> src/main.rs:26:8
|
19 | let data1 = hash.get(&i).unwrap();
| ------------ immutable borrow occurs here
...
26 | hash.insert(j, vec![1,2,3]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
...
29 | let res = do_cal(data1, data2);
| ----- immutable borrow later used here
Run Code Online (Sandbox Code Playgroud)
有关此错误的更多信息,请尝试rustc --explain E0502。playground错误:由于之前的错误而无法编译
考虑一下:借用检查器不知道这hash.insert(j, \xe2\x80\xa6)会留下您插入的数据hash.insert(i, \xe2\x80\xa6)。对于借用检查器,hash.insert(\xe2\x80\xa6)可以对 中的任何元素执行任何操作hash,包括重写或删除它。因此,您不能被允许将引用保留data1在 上hash.insert(j, \xe2\x80\xa6)。
如何克服这个问题?最简单的可能是移动,let data1 = hash.get(\xe2\x80\xa6)这样它就不必存活这么久:
let data1 = hash.get(&i).unwrap();\nlet data2 = hash.get(&j).unwrap();\nlet res = do_cal(data1, data2);\nRun Code Online (Sandbox Code Playgroud)\n当然,这将查找data1每个循环迭代(并且它必须,因为hash.insert(j, \xe2\x80\xa6)可能已经调整了大小,从而重新分配了哈希映射的内容,从而data1在哈希映射中给出了新的存储位置)。为了完整起见,有一些方法可以解决这个问题,但我不建议您这样做:
let data1 = hash.get(&i).unwrap().clone()如果你的向量很短,这实际上可能是合理的\xe2\x80\xa6)HashMap<usize, Rc<Vec<usize>>>代替(您只需要克隆Rc,而不是整个Vec)do_call,您可以将Rc与 a结合起来RefCell:Rc<RefCell<Vec<\xe2\x80\xa6>>>Rcs 替换为从凹凸分配器中分配所获得的引用,例如凹凸分配器。| 归档时间: |
|
| 查看次数: |
1520 次 |
| 最近记录: |