我尝试实现自己的find_or_insert
方法,它看起来像这样:
use std::collections::HashMap;
pub struct SomeManager {
next: i32,
types: HashMap<i32, i32>,
}
impl SomeManager {
pub fn get_type<'a>(&'a mut self, k: i32) -> &'a i32 {
match self.types.get(&k) {
Some(ref x) => return *x,
None => {
self.types.insert(k, self.next);
self.next += 1;
return self.types.get(&k).unwrap();
}
}
}
}
fn main() {}
错误:
error[E0502]: cannot borrow `self.types` as mutable because it is also borrowed as immutable
--> src/main.rs:13:17
|
10 | match self.types.get(&k) {
| ---------- immutable borrow occurs here
...
13 | self.types.insert(k, self.next);
| ^^^^^^^^^^ mutable borrow occurs here
...
18 | }
| - immutable borrow ends here
我知道有一些标准方法可以实现这个功能,但我希望这个方法尽可能轻量级 - 它将被频繁调用,而且几乎所有的值都已经存在。
据我所知,当我们调用
self.types.get
时,我们将其借用到match语句的范围内,因此我们无法在此处调用self.types.insert
。我试图将方法从None分支移到match语句之外,但也失败了。我找到的唯一有效的解决方案需要两次调用
get
:pub fn get_type<'a>(&'a mut self, k: i32) -> &'a i32 {
let is_none = match self.types.get(&k) {
Some(ref x) => false,
None => true,
};
if is_none {
self.types.insert(k, self.next);
self.next += 1;
}
self.types.get(&k).unwrap()
}
如何绕过这种情况?
&mut self.path
这样的参数可以传递给一个以self
作为接收器的方法。这真的很棒。 - Vladimir Matveevself
,至少不是和self.path
中的self
相同;它使用的是self.types
,使得借用变得不交叉。 - Chris Morgan