rust - 可变借用超出范围但不能重新借用
问题描述
v
当第一个可变借用似乎超出范围时,我无法理解为什么我不能第二次使用:
fn get_or_insert(v: &mut Vec<Option<i32>>, index: usize, default: i32) -> &mut i32 {
if let Some(entry) = v.get_mut(index) { // <-- first borrow here
if let Some(value) = entry.as_mut() {
return value;
}
}
// error[E0502]: cannot borrow `*v` as immutable because it is also borrowed as mutable
while v.len() <= index { // <-- compiler error here
v.push(None);
}
// error[E0499]: cannot borrow `*v` as mutable more than once at a time
let entry = v.get_mut(index).unwrap(); // <-- compiler error here
*entry = Some(default);
entry.as_mut().unwrap()
}
我的变量范围是否错误,或者借用检查器是否保护我免受我没有看到的东西的影响?
编辑:启用 NLL 的错误消息非常好:
error[E0502]: cannot borrow `*v` as immutable because it is also borrowed as mutable
--> src/main.rs:10:11
|
3 | fn get_or_insert(v: &mut Vec<Option<i32>>, index: usize, default: i32) -> &mut i32 {
| - let's call the lifetime of this reference `'1`
4 | if let Some(entry) = v.get_mut(index) {
| - mutable borrow occurs here
5 | if let Some(value) = entry.as_mut() {
6 | return value;
| ----- returning this value requires that `*v` is borrowed for `'1`
...
10 | while v.len() <= index {
| ^ immutable borrow occurs here
解决方案
关键是,即使使用 NLL,返回值的生命周期也会跨越整个函数。v
在决定是否可以在较低的代码中访问引用时,没有考虑函数在第 4 行提前返回的事实。
@Stargateur 建议的修复方法是在访问元素之前根据需要增大向量:
fn get_or_insert(v: &mut Vec<Option<i32>>, index: usize, value: i32) -> &mut i32 {
if v.len() < index {
v.resize(index + 1, None);
}
v[index].get_or_insert(value)
}