什么时候需要使用生命周期?

D. *_*aro 7 rust

我已经阅读了生命周期并了解每个变量绑定都有生命周期。然而,我似乎想不出什么时候你实际上需要使用它们,因为编译器在必要时在推断它们方面做了很多工作。

《Rust》这本书,我读过。我想要一个简单易懂的例子,即使对于像我这样的人来说也是如此!

Fra*_*gné 9

当一个变量(有一定的生命周期)引用另一个具有不同生命周期的变量时,我们在 Rust 中使用生命周期参数。

让我们考虑一下这两个陈述:

let i = 42;
let ref_i = &i;
Run Code Online (Sandbox Code Playgroud)

这里,i有一些一生,也ref_i有另外一些一生。然而,类型ref_i编码了生命周期i(或者它的某种近似值);写入借用指针的类型&'a T,并且'a是指针所指对象的生命周期。

借用指针只能引用生命周期比指针生命周期长的值。如果不是这种情况,那么指针最终将是悬空的,即它将引用一个不再存在的值。编译器会自动为您验证这一点(只要您不编写unsafe代码);这是其他系统编程语言(例如 C++)无法做到的事情。但为了验证这一点,编译器必须知道指针引用的值的生命周期;这就是为什么我们在 Rust 中有生命周期参数。幸运的是,编译器还可以在许多情况下推断生命周期,因此在这些情况下它是透明的。

按照设计,Rust 只会进行本地类型推断。编译函数时,编译器不会检查其他函数或其他类型的主体来验证第一个函数是否正确;它只看他们的签名。对于函数,我们有省略规则,规定何时可以省略显式生命周期参数以及编译器将推断它们是什么。对于结构体,我们总是必须显式地提及它们,因为我们几乎总是需要将结构体上的生命周期参数与其他一些项目相关联(例如,特征实现中特征的生命周期参数,或方法的返回类型),由于编译器只进行本地类型推断,我们需要在签名中显式编码这种相关性。

下面是一个包含借用的结构的简单示例:

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

impl<'a> Wrapper<'a> {
    fn extract(self) -> &'a str {
        self.0
    }
}
Run Code Online (Sandbox Code Playgroud)

首先,在结构体定义上,我们需要为字符串切片引入一个生命周期参数。然后,我们需要参数化 the impl,因为Wrapper需要一个生命周期参数(in'a定义impl<'a> 生命周期参数,in'a使用Wrapper<'a> 生命周期参数)。在 上extract,我们可以引用'a上定义的生命周期参数impl,以便函数的返回类型与 的实际类型相匹配self.0