显示标注

借用检查器使用显式的生命周期来明确引用的有效时间应该持续多久。在生命周期没有省略[^1]的情况,Rust 需要显式标注来确定引用的生命周期应该是什么样的。对于显式地标注引用的生命周期的语法如下:

  1. foo<'a>
  2. // `foo` 带有一个生命周期参量 `'a`

闭包类似,使用生命周期需要泛型。另外这个生命周期的语法也表明了 foo 的生命周期不能超出 'a 的周期。类型的显式标注有 &'a T 这样的形式,其中 'a 已引入。

In cases with multiple lifetimes, the syntax is similar:
对于多个生命周期的情况,语法是类似的:

  1. foo<'a, 'b>
  2. // `foo` 带有生命周期参量 `'a` 和 `'b`

在这种情形中,foo 的生命周期不能超出 'a'b 的周期。

看下面的例子,了解显式生命周期标注的运用:

  1. // 生命周期 `'a` 和 `'b`。这两个生命周期都必须至少要和 `print_refs`
  2. // 函数的一样长。
  3. fn print_refs<'a, 'b>(x: &'a i32, y: &'b i32) {
  4. println!("x is {} and y is {}", x, y);
  5. }
  6. // 不带参量的函数,不过有一个生命周期参量 `'a`。
  7. fn failed_borrow<'a>() {
  8. let _x = 12;
  9. // 报错:`_x` 存活时间长度不够(`_x` does not live long enough)
  10. //let y: &'a i32 = &_x;
  11. // 尝试使用生命周期 `'a` 作为函数内部的显式类型标注将导致失败,因为
  12. // `&_x` 的生命周期比 `y` 的短。短生命周期不能强制转换成长生命周期。
  13. }
  14. fn main() {
  15. // 创建变量,给下面代码借用。
  16. let (four, nine) = (4, 9);
  17. // 两个变量的借用(`&`)都传进函数。
  18. print_refs(&four, &nine);
  19. // 任何借用得来的输入量都必须比借入者“活”得更长。
  20. // 也就是说,`four` 和 `nine` 的生命周期都必须比 `print_refs`
  21. // 的长。
  22. failed_borrow();
  23. // `failed_borrow` 未包含引用来迫使 `'a` 长于函数的生命周期,
  24. // 但 `'a` 寿命更长。因为该生命周期从未被约束,所以默认为 `'static`。
  25. }

[^1]: 省略 隐式地标注了生命周期,所以情况不同。

参见:

泛型闭包