我啥时候需要在 Rust 中指定显式生命周期?

Posted

技术标签:

【中文标题】我啥时候需要在 Rust 中指定显式生命周期?【英文标题】:When do I need to specify explicit lifetimes in Rust?我什么时候需要在 Rust 中指定显式生命周期? 【发布时间】:2015-09-14 00:45:12 【问题描述】:

如果我有这两个功能

// implicit
fn foo(x: &i32) 


// explicit
fn bar<'a>(x: &'a i32) 

foo 何时返回错误,bar 何时成为正确的函数头?我很困惑为什么我会明确声明一个生命周期:

“a”读作“生命 a”。从技术上讲,每个参考文献都有一些 与之相关的生命周期,但编译器允许您将它们省略 常见情况。

我了解生命周期是什么,但明确指定生命周期'a对我有什么作用?作为参考,我使用Rust book 作为阅读材料

【问题讨论】:

【参考方案1】:

实际上,您必须编写生命周期注释的第一个原因是因为编译器会这样要求您。它将拒绝lifetime elision rules 未涵盖的函数签名。

我假设您想要一个简单的示例,其中生命周期是强制性的。想象以下场景:

struct Blah<'a> 
    hoy: &'a u8


fn want_a_hoy(blah: &Blah) -> &u8 
    blah.hoy

意图很明显,但编译器不处理:

<anon>:7:35: 7:38 error: missing lifetime specifier [E0106]
<anon>:7     fn want_a_hoy(blah: &Blah) -> &u8 
                                           ^~~
<anon>:7:35: 7:38 help: see the detailed explanation for E0106
<anon>:7:35: 7:38 help: this function's return type contains a borrowed value, but 
                        the signature does not say which one of `blah`'s 2 elided 
                        lifetimes it is borrowed from

在这种情况下,注解解决了问题:

fn want_a_hoy<'a, 'b>(blah: &'b Blah<'a>) -> &'a u8 
    blah.hoy

在这里您指定了两次'a(在Blah&lt;'a&gt;&amp;'a 上)。这是一样的一生!所以你在这里对编译器说的是:“这个函数需要一个对包含内部引用的 blah 的引用。我将返回与 blah 的内部引用一样长的东西。”在这种情况下,签名强烈暗示您可能会返回来自 blah 内部的东西。

【讨论】:

一个更简单的生命周期省略失败的例子是fn pick_one(a: &amp;T, b: &amp;T) -&gt; &amp;T(即使它总是无条件地返回其中一个)。

以上是关于我啥时候需要在 Rust 中指定显式生命周期?的主要内容,如果未能解决你的问题,请参考以下文章

在 Rust 中与生命周期的子类型关系作斗争

使用字符串时 Rust 中的生命周期

什么是非词汇生命周期?

在 Rust 中使用带有结构的生命周期的正确方法是啥?

指定 Rust 闭包的生命周期

如何在 Keycloak 中指定刷新令牌的生命周期