如果生命周期未被使用,为什么在引用类型上实现特征时需要生命周期,在Rust <1.31?

Est*_*eis 9 lifetime rust

我正在使用早于1.31的Rust实现引用类型的特征.当我告诉它我正在实现特征的引用类型时,为什么Rust需要明确的生命周期?

这是一个简单的例子.结构Inches, Add特性的实现&Inches,以及使用该实现的函数.

最初的例子

(Rust操场链接)

use std::ops::Add;

struct Inches(i32);

// this would work: impl<'b> Add for &'b Inches
impl Add for &Inches {
    type Output = Inches;

    fn add(self, other: &Inches) -> Inches {
        let &Inches(x) = self;
        let &Inches(y) = other;

        Inches(x + y)
    }
}

// lifetime specifier needed here because otherwise 
// `total = hilt + blade` doesn't know whether `total` should live
// as long as `hilt`, or as long as `blade`.
fn add_inches<'a>(hilt: &'a Inches, blade: &'a Inches) {
    let total = hilt + blade;
    let Inches(t) = total;
    println!("length {}", t);
}

fn main() {
    let hilt = Inches(10);
    let blade = Inches(20);

    add_inches(&hilt, &blade);
}
Run Code Online (Sandbox Code Playgroud)

编译失败,并出现以下错误:

error: missing lifetime specifier [E0106]
    impl Add for &Inches {
                 ^~~~~~~
Run Code Online (Sandbox Code Playgroud)

我添加了缺少的生命周期说明符(仍然没有编译)

// was: impl Add for &Inches {
impl Add for &'b Inches {
    ...
}
Run Code Online (Sandbox Code Playgroud)

编译错误:

error: use of undeclared lifetime name `'b` [E0261]
    impl Add for &'b Inches {
Run Code Online (Sandbox Code Playgroud)

我声明了生命周期impl(现在它编译)

(Rust操场链接)

// was: impl Add for &'b Inches {
impl<'b> Add for &'b Inches {
    ...
}
Run Code Online (Sandbox Code Playgroud)

最后,这正确编译.

我的问题

为什么&Inchesimpl Add for &Inches认为缺乏一辈子符?通过告诉编译器这个Add方法是针对&Inches某些未指定的非静态生命周期'b,然后在其他地方从不引用该生命周期,可以解决什么问题?

mdu*_*dup 10

Rust 1.31及以上

原因很简单:直到Rust 1.31才实现.

现在,初始示例编译,您可以编写impl Add for &Inches而不是impl<'b> Add for &'b Inches.这是因为1.31.0 稳定了新的终身省略规则.

在Rust之前1.31

如果您查看RFC for lifetime elision,您可以看到您的用例应该包含在内:

impl Reader for BufReader { ... }                       // elided
impl<'a> Reader for BufReader<'a> { .. }                // expanded
Run Code Online (Sandbox Code Playgroud)

但是,我在操场上尝试过它并没有用.原因是它还没有实现.

我为这些案例编写了Rust的源代码,但令人惊讶的是它们很少.我只能Add在本机类型上找到这一系列的实现:

impl Add<u8> for u8
impl<'a> Add<u8> for &'a u8
impl<'a> Add<&'a u8> for u8
impl<'a, 'b> Add<&'a u8> for &'b u8
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,这里的生命周期都是明确的; 不会出现任何缺陷.

对于您的具体问题,我相信您必须坚持使用显式生命周期,直到RFC实现完成!

  • 一生中仍然存在.Elision规则表明编译器如何在编译时解决缺失的生命周期,避免编写"明显的"样板注释.是的,他们必须得到呼叫者的尊重,但反过来,这些呼叫者可以从代码的相关部分中获益. (3认同)