调用 return 引用的函数时了解非词法生命周期
Understanding non lexical lifetimes when calling functions that return reference
以下函数对于 NLL
工作正常
fn main() {
let mut x = 1i32;
let mut y = &mut x;
let z = &mut y;
*y = 12;
}
但是,如果我用函数调用(基本上做同样的事情)替换语句 let z = &mut y
,借用检查器会抱怨。
fn test<'a>(x:&'a mut &'a mut i32) -> &'a mut i32 {
&mut **x
}
fn main() {
let mut x = 1i32;
let mut y = &mut x;
let z = test(&mut y);
*y = 12;
}
给出以下错误:
error[E0506]: cannot assign to `*y` because it is borrowed
--> src/main.rs:11:5
|
9 | let z = test(&mut y);
| ------ borrow of `*y` occurs here
10 |
11 | *y = 12;
| ^^^^^^^
| |
| assignment to borrowed `*y` occurs here
| borrow later used here
函数test()
返回的引用已经不用了,难道不应该考虑'dead'吗?
让我们为程序中的生命周期命名。 (这不会编译,但用于演示目的。)
在您的第一个示例中,我们有两个生命周期,'1
和 '2
。生命周期 '2
只持续一行,所以 y
可以在以后使用:
fn main() {
let mut x = 1i32; //
let mut y = &'1 mut x; // ^
// |
let z = &'2 mut y; // |'2 |'1
// |
*y = 12; // v
}
在第二个示例中,因为 test
需要 &'a mut &'a mut i32
,其中 'a
表示相同的生命周期,外部引用必须与内部引用一样长。这就是我们收到错误的原因:
fn test<'a>(x:&'a mut &'a mut i32) -> &'a mut i32 {
&mut **x
}
fn main() {
let mut x = 1i32; //
let mut y = &'1 mut x; // ^
// |
let z = test(&'2 mut y); // |'2 |'1
// | |
*y = 12; // v v
}
但是,如果我们给 test
两个不同的生命周期,代码现在可以正常编译,因为我们回到了与第一个示例相同的情况:
fn test<'a, 'b>(x:&'a mut &'b mut i32) -> &'a mut i32 {
&mut **x
}
fn main() {
let mut x = 1i32; //
let mut y = &'1 mut x; // ^
// |
let z = test(&'2 mut y); // |'2 |'1
// |
*y = 12; // v
}
以下函数对于 NLL
工作正常fn main() {
let mut x = 1i32;
let mut y = &mut x;
let z = &mut y;
*y = 12;
}
但是,如果我用函数调用(基本上做同样的事情)替换语句 let z = &mut y
,借用检查器会抱怨。
fn test<'a>(x:&'a mut &'a mut i32) -> &'a mut i32 {
&mut **x
}
fn main() {
let mut x = 1i32;
let mut y = &mut x;
let z = test(&mut y);
*y = 12;
}
给出以下错误:
error[E0506]: cannot assign to `*y` because it is borrowed
--> src/main.rs:11:5
|
9 | let z = test(&mut y);
| ------ borrow of `*y` occurs here
10 |
11 | *y = 12;
| ^^^^^^^
| |
| assignment to borrowed `*y` occurs here
| borrow later used here
函数test()
返回的引用已经不用了,难道不应该考虑'dead'吗?
让我们为程序中的生命周期命名。 (这不会编译,但用于演示目的。)
在您的第一个示例中,我们有两个生命周期,'1
和 '2
。生命周期 '2
只持续一行,所以 y
可以在以后使用:
fn main() {
let mut x = 1i32; //
let mut y = &'1 mut x; // ^
// |
let z = &'2 mut y; // |'2 |'1
// |
*y = 12; // v
}
在第二个示例中,因为 test
需要 &'a mut &'a mut i32
,其中 'a
表示相同的生命周期,外部引用必须与内部引用一样长。这就是我们收到错误的原因:
fn test<'a>(x:&'a mut &'a mut i32) -> &'a mut i32 {
&mut **x
}
fn main() {
let mut x = 1i32; //
let mut y = &'1 mut x; // ^
// |
let z = test(&'2 mut y); // |'2 |'1
// | |
*y = 12; // v v
}
但是,如果我们给 test
两个不同的生命周期,代码现在可以正常编译,因为我们回到了与第一个示例相同的情况:
fn test<'a, 'b>(x:&'a mut &'b mut i32) -> &'a mut i32 {
&mut **x
}
fn main() {
let mut x = 1i32; //
let mut y = &'1 mut x; // ^
// |
let z = test(&'2 mut y); // |'2 |'1
// |
*y = 12; // v
}