rust 中的生命周期是 rust 特有的一个概念,用于标识一个变量的生命长度。
不能访问一个超出其生命周期的变量。我们可以用 {}
来显式的标识生命周期。
'a{
let a = 1;
let b = 2;
'b{
b
}
//编译失败,变量 b 的生命周期已经结束。
println!("b is {}", b);
}
代码中变量 a 的生命周期为 'a,变量 b 的生命周期为 'b,a 活的比 b 要长。
这种情况下编译器可以明确的知道变量的生命周期边界,是不需要标注生命周期参数的。
那么什么情况下需要标注生命周期参数呢?
情况一,函数返回引用。
fn larger_str(a: &str, b: &str) -> &str {
if a > b {
return a;
}
b
}
fn main() {
let a = String::from("hello");
let b = String::from("world");
let c = larger_str(&a, &b);
{
b
}
//无法编译,编译器无法判断现在的 c 是否还是一个有效的引用。
println!("c is {}", c);
}
正常情况下,编译时是不会知道函数的运行结果的,因此上面代码中编译器是不知道 c
最终指向的是 a
还是 b
,因此无法判断 c
是否还是一个有效的引用。
显然这种情况下 c
的生命周期取决于 a
和 b
中生命周期较小的那一个。那么如何在代码里标识这种情况呢?
fn larger_str<'a>(a: &'a str, b: &'a str) -> &'a str {
if a > b {
return a;
}
b
}
情况二,结构体中的引用
struct Foo {
a: &str,
b: String,
}
fn main() {
let s = String::from("hello");
let f = Foo{a: &s, b: String::from("world")};
//编译失败,编译器无法确定结构体中的引用是否还有效。
println!("foo is {}", f.b);
}
因此,需要加上生命周期参数,标识结构体内的引用不能小于结构体的生命周期。如下所示。
struct Foo<'a> {
a: &'a str,
b: String,
}
fn main() {
let s = String::from("hello");
let f = Foo{a: &s, b: String::from("world")};
//编译失败,编译器无法确定结构体中的引用是否还有效。
println!("foo is {}", f.b);
}
网友评论