Rust 中 "p: &'a i32" 和 "p: &'static i32" 生命周期的区别?

Difference between "p: &'a i32" and "p: &'static i32" lifetime in Rust?

几天前我开始学习 Rust。

这是 Jim Blandy 着名著作 Programming Rust 的摘录。

求代码

fn g<'a>(p: &'a i32) { ... }

let x = 10;
g(&x);

书上说

Rust Choose the smallest possible lifetime for &x, that of the call to g. This meets all constraints: it doesn't outlive x, and encloses the entire call to g. So code must muster.

Q1。 &x 的最小生命周期是什么意思?

求代码

fn f(p: &'static i32) { ... }

let x = 10;
f(&x);

Q2。为什么这段代码会失败?根据我的理解,&'static 用于整个程序的静态全局变量。 link

引用的 'static 生命周期要求要求为程序的全局生命周期声明此参数,但 x 无法满足此条件,因为它是在执行中途声明的。

为了能够使用它,请将 x 声明为 conststatic,这样它的生命周期将为 'static,并且代码可以正常工作。

'static生命周期是一个特殊的概念。它指定 this 引用的变量需要在程序的 整个 生命周期内存在。使用这种情况很少见,需要更罕见的预防措施才能实现。

实际上,&'static 引用可能只在两种情况下发生:

  • 一个const声明
  • 一个static声明

两者都以不同的方式有效地完成了同一件事;但是,这些差异对这个问题并不重要。在这两种情况下,结果都是一个变量,该变量在程序的整个生命周期内都可用,并且不会被重新定位,因此保证 &'static 如果借用。

既然我们已经讨论了这个,让我们来讨论你的两个问题。


Q1. What is meant by the smallest possible lifetime for &x?

当您将函数定义为 fn g<'a>(p: &'a i32) { ... } 时,您要求 p 在生命周期内有效 'a;此生命周期由编译器确定,因此 'a 可能的最小值 。例如,如果引用从未在函数范围之外使用,则 'a 将是该函数执行的生命周期。如果您在函数外使用或引用此借用,则生命周期(显然)会更长。

"smallest possible" 的定义很简单:编译器将根据您开始该引用的时间到您最后一次使用该引用的时间来推断生命周期。依赖借用也很重要,这通常会在处理 collections.

时反过来咬人

它尽可能小的原因是您不会 运行 陷入没有借用但无论如何都被借用的疯狂情况;这通常发生在您尝试提供自己的、不正确的、生命周期提示时。在很多情况下,通常最好让编译器来决定;另一种情况是 struct 实现,例如:

struct Foo<'a> {
    item: &'a u32
}
impl<'a> Foo<'a> {
    pub fn compare<'b>(&self, other: &'b u32) {
        ...
    }
}

在这种情况下的一个常见错误是向编译器描述 other'a 而不是 定义第二个 'b 生命周期,因此(意外地)要求在 struct 本身的生命周期内借用 other


Q2. Why does this code fail? According to my understanding, &'static is used for static global variables which live for the full program.

let x = 10;

此分配没有 'static 生命周期。它有一个定义为小于 'static 的匿名生命周期,因为它不是 严格地 定义为全局的。 获得 'static 借用任何东西的方法是,如果该源元素定义为 conststatic.

您可以通过以下代码段 (playground) 说服自己:

fn f(p: &'static i32) {
    println!("{}", p)
}

const FOO:i32 = 3;
static BAR:i32 = 4;

fn main() {
    f(&FOO); // Works
    f(&BAR); // Also works
}
f(&x);