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

时间:2015-05-23 18:41:33

标签: rust lifetime

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

这是一个简单的例子。结构Inches,一个实现 Add的{​​{1}}特征,以及使用该实现的函数。

初始示例

(Rust playground link)

&Inches

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

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);
}

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

error: missing lifetime specifier [E0106]
    impl Add for &Inches {
                 ^~~~~~~

编译错误:

// was: impl Add for &Inches {
impl Add for &'b Inches {
    ...
}

我在error: use of undeclared lifetime name `'b` [E0261] impl Add for &'b Inches { (现在编译)

上声明了生命周期

(Rust playground link)

impl

最后,这可以正确编译。

我的问题

  

为什么// was: impl Add for &'b Inches { impl<'b> Add for &'b Inches { ... } 中的&Inches被认为缺少   终身说明?告诉编译器解决了什么问题   此Add方法适用于impl Add for &Inches,其中包含一些未指定的非静态方法   一生&Inches,然后永远不会在任何地方引用那个生命周期   别的?

1 个答案:

答案 0 :(得分:10)

Rust 1.31及以上

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

现在,初始示例已编译,您可以编写impl Add for &Inches而不是impl<'b> Add for &'b Inches。这是因为1.31.0 stabilized new lifetime elision rules

Rust 1.31

之前

如果查看RFC for lifetime elision,您可以看到应该涵盖您的用例:

impl Reader for BufReader { ... }                       // elided
impl<'a> Reader for BufReader<'a> { .. }                // expanded

但是,我在操场上试了it doesn't work。原因是it's not implemented yet

我为这些案例提供了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

正如你所看到的,生活时间在这里都是明确的;不会出现任何缺陷。

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