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


如果我有这两个功能

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

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

什么时候会 foo 返回错误并且 bar 是正确的函数头?我很困惑 为什么 我会明确宣布一生:

'a读'生命'a'。从技术上讲,每个参考都有一些   与之相关的生命周期,但编译器允许你忽略它们   常见病例。

我理解生命是什么,但明确指定生命周期的是什么 'a   为了我?作为参考,我正在使用 铁锈书 作为阅读材料


2520
2018-06-26 23:55


起源



答案:


实际上,您必须编写终身注释的首要原因是 因为编译器会这么问你。它将拒绝未涵盖的功能签名 终身省略规则

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

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<'a> 和 &'a)。这是一辈子!所以你在这里对编译器说的是:“这个函数引用了一个包含内部引用的blah。我将返回与blah的内部引用完全一样长的东西。”在这种情况下,签名给出了一个强烈的暗示,即你很可能会返回来自blah内部的东西。


10
2018-06-27 00:38



终身省略失败的一个更简单的例子是 fn pick_one(a: &T, b: &T) -> &T (即使它总是无条件地返回其中一个)。
完全有道理,谢谢! - Syntactic Fructose


答案:


实际上,您必须编写终身注释的首要原因是 因为编译器会这么问你。它将拒绝未涵盖的功能签名 终身省略规则

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

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<'a> 和 &'a)。这是一辈子!所以你在这里对编译器说的是:“这个函数引用了一个包含内部引用的blah。我将返回与blah的内部引用完全一样长的东西。”在这种情况下,签名给出了一个强烈的暗示,即你很可能会返回来自blah内部的东西。


10
2018-06-27 00:38



终身省略失败的一个更简单的例子是 fn pick_one(a: &T, b: &T) -> &T (即使它总是无条件地返回其中一个)。
完全有道理,谢谢! - Syntactic Fructose