用非常简单的术语来说,什么是生命周期省略?

What is lifetime elision in very simple terms?

来自the Rust documentation

Rust supports powerful local type inference in the bodies of functions, but it deliberately does not perform any reasoning about types for item signatures. However, for ergonomic reasons, a very restricted secondary inference algorithm called “lifetime elision” does apply when judging lifetimes. Lifetime elision is concerned solely with inferring lifetime parameters using three easily memorizable and unambiguous rules. This means lifetime elision acts as a shorthand for writing an item signature, while not hiding away the actual types involved as full local inference would if applied to it.

我不明白这是什么意思。什么是项目签名? "infer lifetime parameters" 是什么意思?一些示例或类比会有所帮助。

项目签名是给出函数名称和类型的位,即调用它所需的一切(无需知道它是如何实现的);例如:

fn foo(x: u32) -> u32;

这是另一个需要 &str 参考的:

fn bar<'a>(s: &'a str) -> &'a str;

在 Rust 中,所有引用都有附加的生命周期;这是类型的一部分。上面的 bar 函数说的不仅仅是 "this function takes a reference to a string and returns another one"。它说“这个函数接受一个字符串引用,并且 returns 另一个 只要给定它就有效 。这是 Rust 所有权系统的重要组成部分。

然而,每次都指定这些生命周期是很烦人和痛苦的,所以 Rust 有 "lifetime elision"(即 "not explicitly writing them out")。这意味着对于一些非常常见的情况,您可以省略生命周期注释,Rust 会隐式地为您添加它们。这纯粹是为了方便程序员,让他们在 "obvious" 的情况下不必写那么多的生命周期。

规则列在 the book 中,但为了完整起见,它们是:

  1. 函数参数中没有另外指定的每个生命周期都是不同的。例如:
fn f(x: &T, y: &U)

表示:

fn f<'a, 'b>(x: &'a T, y: &'b U)

即这些生命周期之间没有自动 link。

  1. 如果只有一个输入生命周期,则它用于每个输出生命周期。例如:
struct U<'a> {}  // struct with a lifetime parameter

fn f(x: &T) -> &U

变为:

fn f<'a>(x: &'a T) -> &'a U<'a>
  1. 否则,如果有多个输入生命周期,但其中一个是 &self&mut self(即它是一种方法),则所有省略的输出生命周期都与 self.这涵盖了一种常见情况,即方法 returns 对其字段之一的引用。例如:
impl S {
    fn get_my_item(&self, key: &str) -> &str {}
}

变为:

fn get_my_item<'a,'b>(&'a self, key: &'b str) -> &'a str  // use the self lifetime

文档中有更多示例。