泛型生命周期具体化为引用的生命周期还是引用值的生命周期?
Does a generic lifetime materialize as the reference's lifetime or the referenced value's lifetime?
考虑以下程序:
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
的 return 值(在本例中为 c
)应该与其参数具有相同的生命周期(在本例中为 b
). foo
的生命周期约束是如何满足的?
但是,这个程序可以编译,所以我猜foo
的生命周期参数'z
具体化为b
的引用值(a
)的生命周期所以foo
的生命周期限制是否满足?
值有自己的生命周期,但引用也会跟踪它所引用的事物的生命周期。不幸的是,这里没有可用的官方术语。我(和其他一些人)开始使用的术语是具体的生命周期。 main 中有三个变量,因此有三个具体的生命周期:
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
,它具有相同的 "inner lifetime":&'a str
.
值得注意的是,b
本身的生命周期 永远不会 发挥作用。它非常罕见,因为你需要有可变借用和 "extra" 借用:
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
的寿命不够长,您收到错误。
I don't think this model can account for more complicated borrowing relationships. If a
is used again after the println!
, for example, the mutable borrow can't be for the entire lifetime of a
a
的可变借用由 c
持有,但 借用的持续时间 不需要对应于 c
。由于 non-lexical lifetimes(在这种情况下更好地称为 "non-lexical borrows"),c
持有的 a
的借用可以在 println!
之后但在范围结束之前终止.
增强上面的图表以显示 value 的生命周期与 referred-to value 的生命周期结合在括号中:
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); // | |
}
另请参阅:
- Reference does not live long enough in nested structure
考虑以下程序:
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
的 return 值(在本例中为 c
)应该与其参数具有相同的生命周期(在本例中为 b
). foo
的生命周期约束是如何满足的?
但是,这个程序可以编译,所以我猜foo
的生命周期参数'z
具体化为b
的引用值(a
)的生命周期所以foo
的生命周期限制是否满足?
值有自己的生命周期,但引用也会跟踪它所引用的事物的生命周期。不幸的是,这里没有可用的官方术语。我(和其他一些人)开始使用的术语是具体的生命周期。 main 中有三个变量,因此有三个具体的生命周期:
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
,它具有相同的 "inner lifetime":&'a str
.
值得注意的是,b
本身的生命周期 永远不会 发挥作用。它非常罕见,因为你需要有可变借用和 "extra" 借用:
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
的寿命不够长,您收到错误。
I don't think this model can account for more complicated borrowing relationships. If
a
is used again after theprintln!
, for example, the mutable borrow can't be for the entire lifetime ofa
a
的可变借用由 c
持有,但 借用的持续时间 不需要对应于 c
。由于 non-lexical lifetimes(在这种情况下更好地称为 "non-lexical borrows"),c
持有的 a
的借用可以在 println!
之后但在范围结束之前终止.
增强上面的图表以显示 value 的生命周期与 referred-to value 的生命周期结合在括号中:
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); // | |
}
另请参阅:
- Reference does not live long enough in nested structure