原文链接:https://doc.rust-lang.org/nomicon/lifetime-elision.html

省略生命周期

为了让语言的表达方式更人性化,Rust允许函数的签名中省略生命周期。

“生命周期位置”指的是你在类型中可以写生命周期的地方。

  1. &'a T
  2. &'a mut T
  3. T<'a>

生命周期的位置可以在“输入”也可以在“输出”:

  • 对于fn定义的函数,“输入”指的是函数签名中的参数的类型,而“输出”是结果的类型。所以fn foo(s: &str) -> (&str, &str)省略了一个在输入位置处的生命周期和两个结果位置的生命周期。注意,fn方法定义中的输入位置不包括impl头处的生命周期(自然地,对于trait的默认方法,也不包括trait的头的位置)。
  • 在未来,应该也可能会省略impl头位置处的生命周期。

省略的规则如下:

  • 每一个在输入位置省略的生命周期都对应一个唯一的生命周期参数。
  • 如果只有一个输入的生命周期位置(无论省略还是没省略),那个生命周期会赋给所有省略了的输出生命周期。
  • 如果有多个输入生命周期位置,而其中一个是&self或者&mut self,那么self的生命周期会赋给所有省略了的输出生命周期。
  • 除了上述两种情况,其他省略生命周期的情况都是错误的。

几个例子:

  1. fn print(s: &str); // 省略的
  2. fn print<'a>(s: &'a str); // 完整的
  3. fn debug(lvl: usize, s: &str); // 省略的
  4. fn debug<'a>(lvl: usize, s: &'a str); // 完整的
  5. fn substr(s: &str, until: usize) -> &str; // 省略的
  6. fn substr<'a>(s: &'a str, until: usize) -> &'a str; // 完整的
  7. fn get_str() -> &str; // 错误
  8. fn frob(s: &str, t: &str) -> &str; // 错误
  9. fn get_mut(&mut self) -> &mut T; // 省略的
  10. fn get_mut<'a>(&'a mut self) -> &'a mut T; // 完整的
  11. fn args<T: ToCStr>(&mut self, args: &[T]) -> &mut Command // 省略的
  12. fn args<'a, 'b, T: ToCStr>(&'a mut self, args: &'b [T]) -> &'a mut Command // 完整的
  13. fn new(buf: &mut [u8]) -> BufWriter; // 省略的
  14. fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a> // 完整的