简体   繁体   English

Rust 中“p: &'a i32” 和“p: &'static i32” 寿命之间的区别?

[英]Difference between “p: &'a i32” and “p: &'static i32” lifetime in Rust?

I started learning Rust a few days back.几天前我开始学习 Rust。

This is an extract from the famous book Programming Rust by Jim Blandy.这是 Jim Blandy 着名的《 Programming Rust 》一书的摘录。

For the code对于代码

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

let x = 10;
g(&x);

The book says书上说

Rust Choose the smallest possible lifetime for &x, that of the call to g. Rust 为 &x 选择尽可能小的生命周期,即调用 g 的生命周期。 This meets all constraints: it doesn't outlive x, and encloses the entire call to g.这符合所有约束:它不会比 x 寿命长,并且包含对 g 的整个调用。 So code must muster.所以代码必须集合。

Q1. Q1。 What is meant by the smallest possible lifetime for &x ? &x的最小可能生命周期是什么意思?

For the code对于代码

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

let x = 10;
f(&x);

Q2. Q2。 Why does this code fail?为什么这段代码会失败? According to my understanding, &'static is used for static global variables which live for the full program.据我了解, &'static用于 static 全局变量,这些变量适用于整个程序。 link 关联

A 'static lifetime is a special concept. 'static生命周期是一个特殊的概念。 It specifies that the variable referenced by this needs to exist for the entire lifetime of the program.它指定 this 引用的变量需要在程序的整个生命周期内都存在。 Using this is a rare case, and requires even rarer precautions to fulfill.使用这种情况很少见,需要更罕见的预防措施才能完成。

In practice, a &'static reference may only happen in two cases:在实践中, &'static引用可能只发生在两种情况下:

  • A const declaration一个const声明
  • A static declaration static声明

Both effectively accomplish the same thing, in different ways;两者都以不同的方式有效地完成了同一件事; the differences aren't important to this question, however.然而,这些差异对这个问题并不重要。 In both cases, the outcome is a variable that is available for the entire lifetime of the program and will not be relocated, thus guaranteeing &'static if borrowed.在这两种情况下,结果都是一个在程序的整个生命周期内都可用的变量,并且不会被重定位,因此如果借用,则保证&'static

Now that we've covered this, let's cover both of your questions.既然我们已经介绍了这一点,让我们来介绍您的两个问题。


Q1. Q1。 What is meant by the smallest possible lifetime for &x? &x 的最小可能生命周期是什么意思?

When you define a function as fn g<'a>(p: &'a i32) {... } , you are requiring p to be valid for a lifetime 'a ;当您将 function 定义为fn g<'a>(p: &'a i32) {... }时,您需要p终生有效'a ; this lifetime is determined by the compiler so that 'a is the smallest possible .此生命周期由编译器确定,因此'a最小的可能 If the reference is never used outside of the function scope, 'a will be the lifetime of execution of that function, for example.例如,如果引用从未在 function scope 之外使用,则'a将是该 function 的执行生命周期。 If you use or reference this borrow outside of the function, the lifetime will (evidently) be larger.如果您在 function 之外使用或引用此借用,则生命周期(显然)会更长。

The definition of "smallest possible" is simple: the compiler will infer the lifetime based from the time you start that reference, to the last time you use that reference. “尽可能小”的定义很简单:编译器将根据从您开始该引用的时间到您最后一次使用该引用的时间来推断生命周期。 Dependent borrows also count, and this typically comes back to bite people when dealing with collections.从属借用也很重要,在处理 collections 时,这通常会反过来咬人。

The reason it is the smallest possible is so that you don't run into crazy situations where you don't have a borrow but it is borrowed anyway;它尽可能小的原因是这样您就不会遇到没有借钱但无论如何都借钱的疯狂情况; this typically happens when you try to provide your own, incorrect, lifetime hints.当您尝试提供自己的不正确的生命周期提示时,通常会发生这种情况。 There are plenty of cases where it is usually best to let the compiler decide;在很多情况下,通常最好让编译器来决定。 the other case is struct implementations such as the following:另一种情况是struct实现,如下所示:

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

A common fault in situations like this is to describe other to the compiler as 'a , not defining the second 'b lifetime, and thus (accidentally) requiring other to be borrowed for the lifetime of the struct itself.在这种情况下,一个常见的错误是将other描述为编译器'a而不是定义第二个'b生命周期,因此(意外地)要求在struct本身的生命周期内借用other


Q2. Q2。 Why does this code fail?为什么这段代码会失败? According to my understanding, &'static is used for static global variables which live for the full program.据我了解, &'static 用于 static 全局变量,这些变量适用于整个程序。

let x = 10;

This assignment does not have a 'static lifetime.此分配没有'static生命周期”。 It has an anonymous lifetime defined as less than 'static , because it is not strictly defined as global.它的匿名生命周期定义为小于'static ,因为它没有严格定义为全局。 The only way to get a 'static borrow on anything is if that source element is defined as const or static .在任何东西上获得'static借用”的唯一方法是将该源元素定义为conststatic

You can convince yourself of this with this snippet ( 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);

A 'static lifetime requirement on a reference requires this argument to be declared for the global lifetime of the program, but x cannot fulfill this condition as it is declared midway through execution.引用'static生命周期要求要求为程序的全局生命周期声明此参数,但x无法满足此条件,因为它是在执行过程中声明的。

To be able to use this, declare x as const or static so its lifetime will be 'static and the code will work fine.为了能够使用它,请将 x 声明为conststatic ,这样它的生命周期将是'static的”并且代码可以正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM