生命周期
生命周期描述引用(&T / &mut T)有效的作用域区间,记作 'a 等。每个引用都有生命周期;多数情况下由生命周期省略规则自动推断,只在编译器无法唯一确定时需要在签名中写出。
为何需要生命周期
Rust 要禁止悬垂引用:引用不得长于被指向的数据。生命周期把「这道引用最短能活多久」编码进类型。
生命周期参数 'a
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() >= y.len() { x } else { y }
}含义:返回的 &str 不活得比 x、y 中较短的那个更长(此处统一为同一 'a 的交集)。
结构体中的生命周期
若结构体存了引用,字段必须带生命周期参数:
struct Excerpt<'a> {
part: &'a str,
}否则无法说明 part 不能比被引用的字符串活得更久。
生命周期省略(三条规则)
函数签名里在常见模式下可省略 'a:
- 每个输入引用各分配不同生命周期(若只有一个输入引用,则全体共用)。
- 若只有一个输入生命周期,它被赋给所有输出引用。
- 若有多个输入且其中一个是
&self/&mut self,self的生命周期赋给输出(方法常见)。
复杂签名仍会要求显式标注。
'static
'static:引用指向的数据整个程序期间有效(如字符串字面量 "hello" 的类型为 &'static str)。不是「线程存活期」的别名;并发 里 T: 'static 对闭包有额外含义(与线程边界相关)。
与 NLL(非词法生命周期)
现代 Rust 会基于控制流图细化「引用_last 使用点」,比纯词法块更精确,减少误报,但规则本质不变。