我使用早于1.31的Rust实现了引用类型的特征。 当我告诉它实施特征的参考类型时,为什么Rust需要明确的生命周期?
这是一个简单的例子。结构Inches
,一个实现
Add
的{{1}}特征,以及使用该实现的函数。
&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 {
(现在编译)impl
最后,这可以正确编译。
为什么
// was: impl Add for &'b Inches { impl<'b> Add for &'b Inches { ... }
中的&Inches
被认为缺少 终身说明?告诉编译器解决了什么问题 此Add方法适用于impl Add for &Inches
,其中包含一些未指定的非静态方法 一生&Inches
,然后永远不会在任何地方引用那个生命周期 别的?
答案 0 :(得分:10)
原因很简单:直到Rust 1.31才实现。
现在,初始示例已编译,您可以编写impl Add for &Inches
而不是impl<'b> Add for &'b Inches
。这是因为1.31.0 stabilized new lifetime elision rules。
如果查看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实施完成!