为什么需要使用plus运算符(Iterator <Item =&Foo> +'a)为特征添加生命周期?

tor*_*eyy 13 lifetime rust

我在迭代器上应用了一个闭包,我想使用stable,所以我想返回一个盒装Iterator.这样做的显而易见的方法如下:

struct Foo;

fn into_iterator(myvec: &Vec<Foo>) -> Box<dyn Iterator<Item = &Foo>> {
    Box::new(myvec.iter())
}
Run Code Online (Sandbox Code Playgroud)

这是失败的,因为借用检查器无法推断出适当的生命周期.

经过一番研究,我找到了正确的方法来返回迭代器?,这让我想补充一下+ 'a:

fn into_iterator<'a>(myvec: &'a Vec<Foo>) -> Box<dyn Iterator<Item = &'a Foo> + 'a> {
    Box::new(myvec.iter())
}
Run Code Online (Sandbox Code Playgroud)

但我不明白

  • 这是做什么的
  • 为什么需要这里呢

Luk*_*odt 16

有一件事很容易被忽视:如果你有一个特征Bar并且想要一个盒装特征对象Box<dyn Bar>,编译器会自动添加一个'static生命周期界限(如RFC 599中所指定).这意味着,Box<dyn Bar>Box<dyn Bar + 'static>是等价的!

在您的情况下,编译器会自动添加静态绑定,以便...

fn into_iterator(myvec: &Vec<Foo>) -> Box<dyn Iterator<Item = &Foo>>
Run Code Online (Sandbox Code Playgroud)

......相当于:

fn into_iterator(myvec: &Vec<Foo>) -> Box<dyn Iterator<Item = &Foo> + 'static>
Run Code Online (Sandbox Code Playgroud)

现在,生命周期省略规则启动并"连接"两个生命周期槽,这样上面的代码相当于:

fn into_iterator<'a>(myvec: &'a Vec<Foo>) -> Box<dyn Iterator<Item = &'a Foo> + 'static>
Run Code Online (Sandbox Code Playgroud)

但是类型Iter<'a, Foo>(特定的迭代器类型Vec<Foo>)显然不满足边界'static(因为它是借用的Vec<Foo>)!所以我们必须'static通过指定我们自己的生命周期绑定来告诉编译器我们不想要默认绑定:

fn into_iterator<'a>(myvec: &'a Vec<Foo>) -> Box<dyn Iterator<Item = &Foo> + 'a>
Run Code Online (Sandbox Code Playgroud)

现在编译器知道trait对象仅对生命周期有效'a.请注意,我们没有明确需要注释关联Item类型的生命周期!终身省略规则可以解决这个问题.