为什么在Rust中需要显式的生存期? [英] Why are explicit lifetimes needed in Rust?

查看:77
本文介绍了为什么在Rust中需要显式的生存期?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读Rust书的寿命一章 ,而我遇到了这个示例,给出了一个有名的/明确的生存期:

I was reading the lifetimes chapter of the Rust book, and I came across this example for a named/explicit lifetime:

struct Foo<'a> {
    x: &'a i32,
}

fn main() {
    let x;                    // -+ x goes into scope
                              //  |
    {                         //  |
        let y = &5;           // ---+ y goes into scope
        let f = Foo { x: y }; // ---+ f goes into scope
        x = &f.x;             //  | | error here
    }                         // ---+ f and y go out of scope
                              //  |
    println!("{}", x);        //  |
}                             // -+ x goes out of scope

我很清楚,编译器防止的错误是分配给x的引用的 free-after-free :完成内部作用域之后,f和因此&f.x无效,并且不应将其分配给x.

It's quite clear to me that the error being prevented by the compiler is the use-after-free of the reference assigned to x: after the inner scope is done, f and therefore &f.x become invalid, and should not have been assigned to x.

我的问题是,可以很容易地使用 explicit 'a生存期对问题进行分析,而无需 ,例如通过推断对某个引用的引用的非法分配范围更广(x = &f.x;).

My issue is that the problem could have easily been analyzed away without using the explicit 'a lifetime, for instance by inferring an illegal assignment of a reference to a wider scope (x = &f.x;).

在哪些情况下,真正需要显式生存期来防止事后使用"(或其他类?)错误?

In which cases are explicit lifetimes actually needed to prevent use-after-free (or some other class?) errors?

推荐答案

其他答案都具有显着点( fjh的具体示例),但是缺少一件事:为什么编译器告诉您输入错误的显式寿命

The other answers all have salient points (fjh's concrete example where an explicit lifetime is needed), but are missing one key thing: why are explicit lifetimes needed when the compiler will tell you you've got them wrong?

与为什么编译器可以推断出显式类型时为什么需要显式类型"实际上是一个相同的问题.一个假设的例子:

This is actually the same question as "why are explicit types needed when the compiler can infer them". A hypothetical example:

fn foo() -> _ {  
    ""
}

当然,编译器可以看到我正在返回&'static str,那么程序员为什么必须键入它?

Of course, the compiler can see that I'm returning a &'static str, so why does the programmer have to type it?

主要原因是,尽管编译器可以看到您的代码做什么,但它不知道您的意图是什么.

The main reason is that while the compiler can see what your code does, it doesn't know what your intent was.

功能是防火墙对更改代码的影响的自然界限.如果我们允许从代码中完全检查生命周期,那么看起来无害的更改可能会影响生命周期,从而可能导致相距遥远的函数中的错误.这不是一个假设的例子.据我了解,Haskell在您依赖顶级类型的类型推断时会遇到此问题.鲁斯特消除了这个特殊的问题.

Functions are a natural boundary to firewall the effects of changing code. If we were to allow lifetimes to be completely inspected from the code, then an innocent-looking change might affect the lifetimes, which could then cause errors in a function far away. This isn't a hypothetical example. As I understand it, Haskell has this problem when you rely on type inference for top-level functions. Rust nipped that particular problem in the bud.

编译器还有一个效率上的好处-只有函数签名需要解析才能验证类型和生存期.更重要的是,它对程序员具有效率上的好处.如果我们没有明确的生存期,则此函数的作用是:

There is also an efficiency benefit to the compiler — only function signatures need to be parsed in order to verify types and lifetimes. More importantly, it has an efficiency benefit for the programmer. If we didn't have explicit lifetimes, what does this function do:

fn foo(a: &u8, b: &u8) -> &u8

如果不检查源代码就无法分辨,这会违背大量的编码最佳实践.

It's impossible to tell without inspecting the source, which would go against a huge number of coding best practices.

推断非法分配对更大范围的引用

by inferring an illegal assignment of a reference to a wider scope

范围 本质上是生命周期.更清楚一点,生命周期'a通用生命周期参数,可以在编译时根据调用站点在特定作用域内对其进行专门化.

Scopes are lifetimes, essentially. A bit more clearly, a lifetime 'a is a generic lifetime parameter that can be specialized with a specific scope at compile time, based on the call site.

实际上需要显式的生存期来防止错误吗?

are explicit lifetimes actually needed to prevent [...] errors?

一点也不. 生存期是防止错误发生所必需的,但是需要显式生存期来保护几乎没有理智的程序员.

Not at all. Lifetimes are needed to prevent errors, but explicit lifetimes are needed to protect what little sanity programmers have.

这篇关于为什么在Rust中需要显式的生存期?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆