结论:生命周期省略(elision)让编译器在三种明确场景自动补全标注:①每个输入位置的引用参数各获得一个独立生命周期;②若只有一个输入生命周期,它被赋给所有输出引用;③若方法带 &self/&mut self 参数,self 的生命周期赋给所有输出引用。

展开:这三条规则覆盖绝大多数函数签名,所以平时很少需要手写 'a。规则不适用的场景(多个输入引用且返回引用),编译器无法确定返回值借自谁,就会报错要求显式标注。易错点:省略不是"没有生命周期",而是自动填充;规则三正是方法返回引用通常与 self 绑定的原因;当返回的引用实际来自其他参数(而非 self)时必须手写。追问方向:为什么 fn get(s: &str, p: &str) -> &str 无法省略?因为有两个输入生命周期,编译器不知道返回值该跟哪个,若猜错会让调用方在数据释放后误用引用。

fn first(s: &str) -> &str { &s[..1] }
// 等价于 fn first<'a>(s: &'a str) -> &'a str(规则一+二)

impl User {
    fn name(&self) -> &str { &self.name }
    // 等价于 fn name<'a>(&'a self) -> &'a str(规则三)
}