【发布时间】:2018-11-13 18:29:12
【问题描述】:
当第一个可变借用似乎超出范围时,我无法理解为什么我不能第二次使用 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
【问题讨论】:
-
enable nll 给出更精确的错误; play.rust-lang.org/…
-
我无法向您解释为什么它不起作用,但这里有一个解决方案,play.rust-lang.org/…。我想知道我们是否可以将它添加到 std,但我在 Vec 上没有看到任何用例。我认为哈希图更适合这种事情,但如果不了解您项目的所有细节,就无法确定。 doc.rust-lang.org/std/collections/hash_map/…
-
你没有错过任何东西。您的代码实际上是安全的,但借用检查器无法处理这种情况。类型检查器为第一次借用推断 single 生命周期,并且该生命周期必须足够长才能返回
value。if let的两个分支没有两个不同的生命周期。
标签: rust