我有两段关于寿命的 Rust 代码。第一个只有一个生命周期标记<'a>,无法通过编译。第二个有两个生命周期标记<'a, 'b>,可以通过编译。这是什么原因?
第一个:
fn deserialize1<'a, I: Iterator<Item = &'a u8>>(_iter: &'a mut I) {
}
fn deserialize2<'a, I: Iterator<Item = &'a u8>>(_iter: &'a mut I) {
}
fn deserialize3<'a, I: Iterator<Item = &'a u8>>(iter: &'a mut I) {
deserialize1(iter);
deserialize2(iter);
}
fn main() {
let v : Vec<u8> = vec![1, 2, 3];
let mut iter = v.iter();
deserialize3(&mut iter);
}
第二个:
fn deserialize1<'a, 'b, I: Iterator<Item = &'a u8>>(_iter: &'b mut I) {
}
fn deserialize2<'a, 'b, I: Iterator<Item = &'a u8>>(_iter: &'b mut I) {
}
fn deserialize3<'a, 'b, I: Iterator<Item = &'a u8>>(iter: &'b mut I) {
deserialize1(iter);
deserialize2(iter);
}
fn main() {
let v : Vec<u8> = vec![1, 2, 3];
let mut iter = v.iter();
deserialize3(&mut iter);
}
第一个编译失败:
error[E0499]: cannot borrow `*iter` as mutable more than once at a time
--> src/main.rs:33:18
|
31 | fn deserialize3<'a, I: Iterator<Item = &'a u8>>(iter: &'a mut I) {
| -- lifetime `'a` defined here
32 | deserialize1(iter);
| ------------------
| | |
| | first mutable borrow occurs here
| argument requires that `*iter` is borrowed for `'a`
33 | deserialize2(iter);
| ^^^^ second mutable borrow occurs here
我无法理解上面的编译信息。为什么生命周期会影响借用规则?
当您像此处所做的那样使用一生时,您就过度限制了您的参考。为什么迭代器的生命周期have与其生成的引用的生命周期相匹配?它甚至受到更多限制,因为用于迭代器
'a
的 Item
是 invariant 在这种情况下意味着编译器根本无法调整生命周期。
好吧,这里使用单一生命周期有很多不灵活性,但为什么这是一个问题呢?由于
'a
是不变的,并且您将相同的内容传递给以相同方式定义的 deserialize1
和 deserialize2
,这意味着 iter: &'a mut I
意味着每个函数中的完全相同的内容。这两个函数都试图在 iter
的完全相同的生命周期内专门借用 'a
,而 Rust 借用检查器显然不允许这样做。当您引入
iter
使用不同的生命周期
'b
时,您允许编译器为每个可变借用选择不同的生命周期,因此不会发生冲突。
为什么生命周期会影响借用规则?生命周期注释的存在只是为了告知借用检查器如何使用引用。显然,如果与您的使用情况相比,您对生命周期的注释不正确,借用检查器会捕获该情况并显示错误。
'b
。您可以保留
iter
不带注释,并且由于生命周期省略规则,它将与您的第二个变体相同:
fn deserialize1<'a, I: Iterator<Item = &'a u8>>(_iter: &mut I) {}
fn deserialize2<'a, I: Iterator<Item = &'a u8>>(_iter: &mut I) {}
fn deserialize3<'a, I: Iterator<Item = &'a u8>>(iter: &mut I) {
deserialize1(iter);
deserialize2(iter);
}