可变借用不止一次 [英] Mutable borrow more than once
问题描述
这是一个无法编译的简短示例的简短示例.错误在 add1
函数中.如果我在 add2
中这样做,它会起作用,但这不是很 DRY.有更多经验的人能告诉我如何以比 add2
更好的方式克服可变借用多次错误.
This is a short sample of short example that doesn't compile. The error is in the add1
function. It works if I do as in add2
, but this isn't very DRY. Can someone with more experience enlighten me of how to overcome the mutable borrow more than once error in a better way than in add2
.
struct S1 {
full: bool,
v: Vec<u32>,
}
struct S2 {
v: Vec<S1>,
}
impl S2 {
// If last is not full push n to last.v, otherwise push a new S1
// Doesn't work
fn add1(&mut self, n: u32) {
// Let's assume it's not empty
let s1 = self.v.last_mut().unwrap();
if !s1.full {
s1.v.push(n);
} else {
self.v.push(S1 {
full: false,
v: vec![n],
});
}
}
// Works
fn add2(&mut self, n: u32) {
// First getting last as immutable ref and then as mutable ref
let full = self.v.last().unwrap().full;
if !full {
self.v.last_mut().unwrap().v.push(n);
} else {
self.v.push(S1 {
full: false,
v: vec![n],
});
}
}
}
fn main() {}
编译器错误:
error[E0499]: cannot borrow `self.v` as mutable more than once at a time
--> src/main.rs:20:13
|
16 | let s1 = self.v.last_mut().unwrap();
| ------ first mutable borrow occurs here
...
20 | self.v.push(S1 {
| ^^^^^^ second mutable borrow occurs here
...
25 | }
| - first borrow ends here
推荐答案
您有两个选择.
1) 每晚使用并将 #![feature(nll)]
放在文件顶部.
1) Use nightly and put #![feature(nll)]
at the top of your file.
非词法生命周期正好解决了这个问题:即使在 else 块中没有使用 s1
借用,它仍然存在并阻止 self.v
的突变.使用非词法生命周期,编译器会识别 s1
实际上已死并让您再次借用.
Non-lexical lifetimes solve exactly this issue: even though the s1
borrow is not used in the else block, it's still alive and blocking mutation of self.v
. With non-lexical lifetimes, the compiler recognizes that s1
is effectively dead and lets you borrow again.
2) 像这样构造你的代码:
2) Structure your code like this:
fn add1(&mut self, n: u32) {
{ // add a scope around s1 so that it disappears later
let s1 = self.v.last_mut().unwrap();
if !s1.full {
s1.v.push(n);
return; // just return early instead of using else
}
}
self.v.push(S1 {
full: false,
v: vec![n]
});
}
这篇关于可变借用不止一次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!