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

Syn*_*ose 11 rust lifetime-scoping

如果我有这两个功能

// implicit
fn foo(x: &i32) {
}

// explicit
fn bar<'a>(x: &'a i32) {
}
Run Code Online (Sandbox Code Playgroud)

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

'a读'生命'a'.从技术上讲,每个引用都有一些与之相关的生命周期,但编译器允许您在常见情况下忽略它们.

我明白一生是什么,但明确指定一生的'a 事情对我有什么影响?作为参考,我使用Rust书作为阅读材料

mdu*_*dup 10

实际上,您必须编写生命周期注释的首要原因是编译器会问您.它将拒绝生命周期省略规则未涵盖的功能签名.

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

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

fn want_a_hoy(blah: &Blah) -> &u8 {
    blah.hoy
}
Run Code Online (Sandbox Code Playgroud)

目的很明显,但编译器不处理它:

<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
Run Code Online (Sandbox Code Playgroud)

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

fn want_a_hoy<'a, 'b>(blah: &'b Blah<'a>) -> &'a u8 {
    blah.hoy
}
Run Code Online (Sandbox Code Playgroud)

在这里你指定'a两次(打开Blah<'a>&'a).这是一辈子的!所以你在这里对编译器说的是:"这个函数引用了一个包含内部引用的blah.我将返回与blah的内部引用完全一样长的东西." 在这种情况下,签名会强烈暗示您可能会返回来自内部的内容.

  • 终身省略失败的一个更简单的例子是`fn pick_one(a:&T,b:&T) - >&T`(即使它总是无条件地返回其中一个). (4认同)