13

如果我有这两个功能

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

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

什么时候会foo返回错误并bar成为正确的函数头?我对为什么要明确声明生命周期感到困惑:

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

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

4

1 回答 1

11

实际上,您必须编写生命周期注释的第一个原因是因为编译器要求您如此。它将拒绝生命周期省略规则未涵盖的函数签名。

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

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了两次(onBlah<'a>&'a)。这是一样的一生!所以你在这里对编译器说的是:“这个函数需要一个对包含内部引用的 blah 的引用。我将返回与 blah 的内部引用一样长的东西。” 在这种情况下,签名强烈暗示您可能会返回来自 blah 内部的东西。

于 2015-06-27T00:38:55.630 回答