考虑以下方案:
fn main() {
let c; |<-'a
let mut a = "Hello, world!".to_string(); |
{ |
let b = &mut a; |<-'b |
c = foo(b); | |
} |
println!("{}", c) |
}
fn foo<'z>(a: &'z mut str) -> &'z str {
a
}b的生存期为'b,而c的生存期为'a,这比'b长。foo的生存期约束规定foo的返回值(在本例中为c)应该与其参数具有相同的生存期(在本例中为b)。foo的生存期约束如何满足?
但是,这个程序是编译的,所以我想foo的生存期参数'z会变成b的引用值(a)的生存期,从而满足foo的生存期约束。
发布于 2019-08-12 16:56:14
一个值有它自己的生命周期,但是引用也会跟踪它引用的事物的生存期。不幸的是,这里缺少官方术语。我(和其他一些人)已经开始使用的术语是具体的生命周期。主变量有三个,因此有三个具体的生命周期:
fn main() {
let c; // 'c
let mut a = String::new(); // 'a ¦
{ // | ¦
let b = &mut a; // | 'b ¦
c = foo(b); // | | |
} // | |
println!("{}", c) // | |
}a是String,b是&mut String,c是&str。这三个变量都是值,但b和c也是引用。在本例中,b引用a中的值,是&'a mut String。由于c是从b派生的,所以它具有相同的“内部生存期”:&'a str。
值得注意的是,b本身的生命周期--从不使用--起了作用。这是非常罕见的,因为你需要可变的借款和“额外的”借款:
fn main() {
let c;
let mut a = String::new();
{
let mut b = &mut a;
c = foo(&mut b); // Mutably borrowing `b` here
}
println!("{}", c)
}error[E0597]: `b` does not live long enough
--> src/main.rs:6:17
|
6 | c = foo(&mut b);
| ^^^^^^ borrowed value does not live long enough
7 | }
| - `b` dropped here while still borrowed
8 | println!("{}", c)
| - borrow later used here在本例中,传递给foo的值为&'b mut &'a mut String类型,该类型被强制传递到&'b mut str。值b的生存期不够长,因此您将得到错误。
我认为这种模式不能解释更复杂的借贷关系。例如,如果
a在println!之后再次使用,则可变的借入不能用于a的整个生命周期。
a的可变借用由c持有,但借用的持续时间不需要与c的生存期相对应。由于non-lexical lifetimes (在这种上下文中称为“非词法借用”),c持有的a的借用可以在println!之后但在范围结束之前终止。
从上面增强图表,以显示值的生存期和括号中引用的值的生存期:
fn main() {
let c; // 'c
let mut a = String::new(); // 'a ¦
{ // | ¦
let b = &mut a; // | 'b('a) ¦
c = foo(b); // | |('a) |('a)
} // | |('a)
println!("{}", c); // | |('a)
// | |
println!("{}", a); // | |
}另请参阅:
https://stackoverflow.com/questions/57456244
复制相似问题