gpt4 book ai didi

reference - 为什么在Rust中需要显式的生存期?

转载 作者:行者123 更新时间:2023-12-03 11:31:41 26 4
gpt4 key购买 nike

我正在阅读Rust书籍的lifetimes chapter,并且发现了这个示例,这是一个有名的/明确的生命周期:

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的引用的After-after-free:在完成内部作用域之后, f以及因此 &f.x变得无效,并且不应该将其分配给 x

我的问题是,无需使用明确的 'a生存期,就可以轻松解决问题,例如,通过推断对更大范围( x = &f.x;)的引用的非法分配。

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

最佳答案

其他答案都具有显着性点(fjh's concrete example where an explicit lifetime is needed),但是缺少一个关键点:当编译器告诉您错误时,为什么需要显式生存期?

这实际上与“为什么编译器可以推断出显式类型时需要使用显式类型”相同。一个假设的例子:

fn foo() -> _ {  
""
}

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

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

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

编译器还有一个效率上的好处-仅需解析函数签名即可验证类型和生存期。更重要的是,它对程序员具有效率上的好处。如果我们没有明确的生存期,则此函数的作用是:
fn foo(a: &u8, b: &u8) -> &u8

如果不检查源代码就无法分辨,这将与大量的编码最佳实践背道而驰。

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



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

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



一点也不。需要生命周期来防止错误,但是需要显式生命周期来保护几乎没有理智的程序员。

关于reference - 为什么在Rust中需要显式的生存期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60535456/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com