我有一个持久的编译错误,其中Rust抱怨我在尝试可变借用时有一个不可变的借位,但是不可变借用来自另一个范围,而我并没有从中带来任何东西.
我有一些代码检查地图中的值,如果它存在,则返回它,否则它需要以各种方式改变地图.问题是我似乎无法找到让Rust同时执行的方法,即使这两个操作完全分开.
这是一些荒谬的代码,它遵循与我的代码相同的结构并展示了问题:
use std::collections::BTreeMap;
fn do_stuff(map: &mut BTreeMap<i32, i32>, key: i32) -> Option<&i32> {
// extra scope in vain attempt to contain the borrow
{
// borrow immutably
if let Some(key) = map.get(&key) {
return Some(key);
}
}
// now I'm DONE with the immutable borrow, but rustc still thinks it's borrowed
map.insert(0, 0); // borrow mutably, which errors
None
}
Run Code Online (Sandbox Code Playgroud)
这出错了:
error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable
--> src/lib.rs:14:5
|
3 …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个函数,该函数查找返回对 Vec 中现有元素的可变引用,或者如果它不存在则将其插入并返回对新元素的可变引用。
我已经尝试过几次,但借用检查员并不相信。我已将尝试编写的代码简化为下面的示例,该示例给出了相同的错误。
fn mut_find_or_insert<T: PartialEq>(vec: &mut Vec<T>, val: T) -> &mut T {
if let Some(u) = vec.iter_mut().find(|u| **u == val) {
u
} else {
vec.push(val);
vec.last_mut().unwrap()
}
}
Run Code Online (Sandbox Code Playgroud)
Rust 给出了以下编译器错误(通过游乐场链接的完整消息):
error[E0499]: cannot borrow `*vec` as mutable more than once at a time
Run Code Online (Sandbox Code Playgroud)
这似乎应该可以在 Rust 中实现,但是我不清楚如何重新实现它以避免借用检查器错误。
下面的代码涉及一个非常微妙的借用检查器闪避。代码本身描述了推理。问题:
/// Insert a new data element at a given key.
pub fn insert<'a, K: Eq, V>(this: &'a mut Vec<(K, V)>, key: K, val: V) -> &'a mut V {
// Safety: As indicated below, we would like to return val1 directly in the loop,
// but rust will reject this, claiming a double borrow, and we instead use some
// unsafe hacks to circumvent the borrow checker. To show this is safe, consider
// …Run Code Online (Sandbox Code Playgroud) 抱歉,如果这是一个愚蠢的问题,我对 Rust 还比较陌生,只是无法破解这个双重可变借用错误。我正在尝试创建一个 AVL 树方法,该方法可以找到可以插入新节点的适当位置。我不明白我需要做什么才能放弃第一笔借款。
我试图在没有 RC、RefCell 或 Unsafe 的情况下做到这一点 - 尽管我越来越不清楚我的方法是否可行。
pub fn find_pos(&mut self, key: &K) -> &mut Link<K, V>{
let mut current = &mut self.root;
while let Some(node) = current.as_mut() { // <- first mutable borrow
match node.key.cmp(&key) {
Ordering::Equal => break,
Ordering::Greater => {
current = &mut node.right;
},
Ordering::Less => {
current = &mut node.left;
},
}
};
current // <- second mutable borrow
}
Run Code Online (Sandbox Code Playgroud)
我也尝试过与此处描述的解决方案类似的方法,但没有成功。
pub fn find_pos(&mut self, key: …Run Code Online (Sandbox Code Playgroud)