Rust中“ p:&'a i32”和“ p:&'static i32”生存期之间的区别?

时间:2019-10-04 17:11:42

标签: rust lifetime

几天前,我开始学习Rust。

这是吉姆·布兰迪(Jim Blandy)着名的 Programming Rust 的摘录。

对于代码

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

let x = 10;
g(&x);

这本书说

  

Rust为&x选择尽可能短的寿命,即对g的寿命。这符合所有约束:它不会超过x,并且将对g的整个调用括起来。因此,代码一定很合适。

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

对于代码

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

let x = 10;
f(&x);

Q2。为什么此代码失败?根据我的理解,&'static用于静态全局变量,该变量在整个程序中都有效。 link

2 个答案:

答案 0 :(得分:2)

'static的生存期是一个特殊的概念。它指定在程序的整个生命周期中都需要存在由此引用的变量。使用这种情况很少见,甚至需要采取更为罕见的预防措施。

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

  • const声明
  • static声明

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

现在我们已经涵盖了这一点,让我们涵盖您的两个问题。


  

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

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

“尽可能最小”的定义很简单:编译器将根据您启动该引用的时间到您上次使用该引用的时间来推断生命周期。依赖借款也很重要,这通常会在处理托收时咬人。

之所以可能是最小的,是因为这样您就不会遇到没有借贷但总会借到的疯狂情况;当您尝试提供自己的不正确的终生提示时,通常会发生这种情况。在很多情况下,通常最好让编译器决定。另一种情况是struct实现,例如:

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

在这种情况下,常见的错误是将other描述为'a编译器,定义了第二个'b生存期,因此(偶然地) ),要求在other本身的生命周期内借入struct


  

Q2。为什么此代码失败?据我了解,&'static用于整个程序中都存在的静态全局变量。

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);

答案 1 :(得分:1)

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

要使用此功能,请将x声明为conststatic,使其有效期为'static,并且代码可以正常工作。