如果 BTreeMap 的键小于一个值,我想删除 BTreeMap 的键和值:
fn update_confirmed_height(&mut self, new_confirmed_height: u32) {
assert!(new_confirmed_height >= self.confirmed_height);
assert!(new_confirmed_height <= self.current_height);
for height in self.blocks.keys() {
if height < &new_confirmed_height {
self.blocks.remove(&height);
}
}
}
但是self.blocks.remove(&height)
报错:
cannot borrow self.blocks as mutable because it is also borrowed as immutable
答案 0 :(得分:0)
据我所知,有三种解决方案。
我希望有更好的解决方案
答案 1 :(得分:0)
据我所知,这个问题有几个解决方案。如果您能够使用夜间功能,则可以使用 BTreeMap 上的保留方法。请参阅:https://doc.rust-lang.org/std/collections/struct.BTreeMap.html#method.retain。后期编辑:最新的 Rust 版本 (1.53.0) 已经稳定了 BTreeMap 中的 retain 方法,因此现在可以在没有夜间功能的情况下使用它。有关详细信息,请参阅 https://blog.rust-lang.org/2021/06/17/Rust-1.53.0.html。
或者,由于您的密钥似乎是 u32,因此可以轻松复制它们。以下内容应该可以解决问题:
pub fn update_confirmed_height(&mut self, new_confirmed_height: u32) {
let keys = {
let mut keys = vec![];
for (key, _) in self.map.iter() {
if key < &new_confirmed_height {
keys.push(*key);
}
}
keys
};
for key in keys {
self.map.remove(&key);
}
}
另一种解决方案是改变实际地图本身,并创建一个新地图。这将,至少在这个快速版本不在我的脑海中,需要一个值的克隆。
pub fn update_confirmed_height(&mut self, new_confirmed_height: u32) {
self.blocks = {
let mut new_blocks = BTreeMap::new();
for (key, value) in self.blocks.iter() {
if key < &new_confirmed_height {
new_blocks.insert(*key, value.clone());
}
}
new_blocks
}
}
如果你问我,重要的是理解编译器显示该错误的“原因”,以及上述解决方案为何以及如何解决该问题。一旦你这样做了,你也许可以通过一些时间和思考提出比上述更好的解决方案。