When is it required to use lifetimes?

我们两清 提交于 2020-02-04 01:10:31

问题


I have read up on lifetimes and understood that every single variable binding has a lifetime. It seems as though, however, that I cannot think of a time you would actually need to use them, considering the compiler does quite a great worl at inferring them when necessary.

The Rust book, I have read. I would like an example that is simple to understand, even for someone like myself!


回答1:


We use lifetime parameters in Rust when a variable (that has some lifetime) refers to another variable with a different lifetime.

Let's consider these two statements:

let i = 42;
let ref_i = &i;

Here, i has some lifetime, and ref_i has some other lifetime. However, the type of ref_i encodes the lifetime of i (or some approximation of it that is sound); the type of a borrowed pointer is written &'a T, and 'a is the lifetime of the pointer's referent.

Borrowed pointers can only refer to a value that has a longer lifetime than the pointer's lifetime. If that was not the case, then the pointer would eventually be dangling, i.e. it would refer to a value that no longer exists. The compiler automatically validates this for you (so long as you don't write unsafe code); that's something that other systems programming languages like C++ don't do. But in order to validate this, the compiler must know the lifetime of the value that the pointer refers to; that's why we have lifetime parameters in Rust. Fortunately, the compiler can also infer lifetimes in many situations, so it's transparent in these situations.

By design, Rust will only do local type inference. When compiling a function, the compiler doesn't inspect the body of other functions or other types to verify that the first function is correct; it only looks at their signature. For functions, we have elision rules that dictate when we can omit explicit lifetime parameters and what the compiler will infer them to be. For structs, we always have to mention them explicitly, because we almost always need to correlate the lifetime parameter on the struct with some other item (e.g. the lifetime parameter of a trait in a trait impl, or the return type on a method), and due to the compiler only doing local type inference, we need to encode this correlation explicitly in the signature.

Here's a simple example of a struct that contains a borrow:

struct Wrapper<'a>(&'a str);

impl<'a> Wrapper<'a> {
    fn extract(self) -> &'a str {
        self.0
    }
}

First, on the struct definition, we need to introduce a lifetime parameter for the string slice. Then, we need to parameterize the impl because Wrapper expects a lifetime parameter (the 'a in impl<'a> defines the lifetime parameter, the 'a in Wrapper<'a> uses the lifetime parameter). On extract, we can refer to the 'a lifetime parameter defined on the impl so that the function's return type matches the actual type of self.0.



来源:https://stackoverflow.com/questions/41654864/when-is-it-required-to-use-lifetimes

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!