这是一个概念性的问题,但此代码不编译:
struct HashHolder{
pub thing: HashMap<usize, usize>,
}
impl HashHolder {
fn insert(&mut self, item: &usize) {
let test = self.thing.get(item).clone(); // immutable borrow occurs here
for i in 0..10 {
match test { // immutable borrow later used here
Some(t) => {
//nothing
},
None => {
self.thing.insert(0, item.clone()); // mutable borrow occurs here
}
}
}
}
}
它给出了"error[E0502]:不能将self.thing
作为可变项borrow ,因为它也是作为不可变项borrow 的",并突出显示了上面显示的行.
然而,如果我go 掉for
循环,它编译得很好!对我来说,这样的编译应该不会有任何问题:match
的范围在循环的每次迭代中都会结束,所以所有引用都应该是" fresh 的".如果我删除循环并再次复制粘贴match
块,也会产生相同的错误.
我对参考/borrow 的理解是:
-
self
是永久borrow 的self.thing.get(item)
.但在clone()
之后,它应该释放那笔借款吗? -
self
在self.thing.insert(...);
处可变borrow ,但一旦insert
完成执行,该borrow 也应被释放.
所以我不明白为什么会发生这种错误.此外,编译器突出显示的行是无用的,因为这三行without the for loop完全可以!
在我对这段代码中发生的事情的理解上有什么错误吗?如果我想多次匹配,什么样的 struct 会更好?
这种方法的部分原因是,在我的实际项目中,test
的值在循环中会有所不同,并且在某些情况下可以给定一个值,因此match
在不同的迭代中可能表现不同.也许这不是实现我想要的行为的最佳方法,但我仍然想理解为什么它甚至无法编译.