生命周期

生命周期描述引用&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 不活得比 xy 中较短的那个更长(此处统一为同一 'a 的交集)。


结构体中的生命周期

若结构体存了引用,字段必须带生命周期参数:

struct Excerpt<'a> {
    part: &'a str,
}

否则无法说明 part 不能比被引用的字符串活得更久


生命周期省略(三条规则)

函数签名里在常见模式下可省略 'a

  1. 每个输入引用各分配不同生命周期(若只有一个输入引用,则全体共用)。
  2. 若只有一个输入生命周期,它被赋给所有输出引用
  3. 若有多个输入且其中一个是 &self / &mut selfself 的生命周期赋给输出(方法常见)。

复杂签名仍会要求显式标注。


'static

'static:引用指向的数据整个程序期间有效(如字符串字面量 "hello" 的类型为 &'static str)。不是「线程存活期」的别名;并发T: 'static 对闭包有额外含义(与线程边界相关)。


与 NLL(非词法生命周期)

现代 Rust 会基于控制流图细化「引用_last 使用点」,比纯词法块更精确,减少误报,但规则本质不变


相关链接