生命周期 Lifetime
生命周期注解 'a、函数签名中的生命周期、生命周期省略规则
生命周期 Lifetime
生命周期是 Rust 编译器用来保证引用始终有效的机制——大多数时候自动推导,复杂场景需要标注 'a。
学完本章你将: 掌握生命周期注解 'a、函数签名中的生命周期、省略规则。
为什么需要生命周期
rust
// ❌ 编译器不知道返回哪个参数
fn longest(x: &str, y: &str) -> &str {
if x.len() > y.len() { x } else { y }
}
// error: missing lifetime specifier
// ✅ 告诉编译器:返回值和 x、y 至少活得一样长
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() { x } else { y }
}
let s1 = String::from("short");
let s2 = String::from("loooooong");
let result = longest(&s1, &s2);
println!("{}", result); // "loooooong"
生命周期省略规则(三法则)
编译器在以下情况自动推导生命周期:
- 每个引用参数都有独立的生命周期
- 如果只有一个输入生命周期,赋给所有输出
- 如果有
&self/&mut self,赋给所有输出
rust
// 无需标注——符合规则 2
fn first_word(s: &str) -> &str { ... }
// 无需标注——符合规则 3
impl Foo {
fn bar(&self, x: &str) -> &str { ... }
}
结构体中的生命周期
rust
// 结构体持有引用时必须标注生命周期
struct Excerpt<'a> {
part: &'a str,
}
impl<'a> Excerpt<'a> {
fn announce(&self, msg: &str) -> &str {
println!("{}", msg);
self.part
}
}