我有一个持久的编译错误,其中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) 下面的代码涉及一个非常微妙的借用检查器闪避。代码本身描述了推理。问题:
/// 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,在尝试将Dikjstra作为培训项目的一部分时,我遇到了这种特殊的问题.首先我定义一个HashMap:
let mut dist: HashMap<Node, usize> = HashMap::new();
Run Code Online (Sandbox Code Playgroud)
然后:
let state = State { node: next_node.clone(), cost: cost + 1 };
let current_dist = dist.get(&state.node);
if (current_dist == None) || (state.cost < *current_dist.unwrap()) {
dist.insert(state.node.clone(), state.cost);
heap.push(state);
}
Run Code Online (Sandbox Code Playgroud)
这产生了一个编译错误,因为dist.get触发了一个不可变的借位,它在if ... {...}语句之后一直保留在范围内,特别是当我dist.insert要求一个可变的借位时.
我想我错过了一个模式或关键字,允许我这种类型的过程.现在我尝试了范围drop的开头if,以及其他current_dist评估
let current_dist;
{
current_dist = dist.get(&state.node);
}
Run Code Online (Sandbox Code Playgroud)
要么
let current_dist = {|| dist.get(&state.node)}();
Run Code Online (Sandbox Code Playgroud)
但是,在if声明之后,仍然会发生不可变借款的范围.
我有一个Vec<State>列表,想要搜索一个元素并获取对其的可变引用。如果不存在,则应创建一个新的默认元素并将其添加到列表中:
struct State {
a: usize,
}
fn print_states(states: &Vec<State>) {
for state in states {
print!("State{{a:{}}} ", state.a);
}
println!();
}
fn main() {
let mut states = vec![State { a: 1 }, State { a: 2 }, State { a: 3 }];
print_states(&states);
let mut state = match states.iter_mut().find(|state| state.a == 2) {
Some(state) => state,
None => {
let new_state = State { a: 3 };
states.push(new_state);
states.last().unwrap()
}
};
state.a = 4;
drop(state);
print_states(&states); …Run Code Online (Sandbox Code Playgroud)