2017-02-03 90 views
4

我在迭代器上应用闭包,我想使用stable,所以我想返回一个盒装Iterator。显而易见的方法如下:为什么Box <Iterator <Item = &Foo> +'a>需要?

struct Foo; 

fn into_iterator(myvec: &Vec<Foo>) -> Box<Iterator<Item = &Foo>> { 
    Box::new(myvec.iter()) 
} 

这会失败,因为借用检查器无法推断出适当的生存期。

经过一番研究,我发现Correct way to return an Iterator?,这给我带来了增加+ 'a

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

但我不明白

  • 这样做有什么
  • ,为什么它是这里需要

回答

8

有一件事情很容易被忽略:如果您有一个特征Foo并且您想拥有盒装特征对象Box<Foo>,则编译器会自动添加一个'static使用期限(如RFC 599中所述)。这意味着Box<Foo>Box<Foo + 'static>是等效的!

在你的情况,编译器会自动添加约束,使得这种静态...

fn into_iterator(myvec: &Vec<Foo>) -> Box<Iterator<Item = &Foo>> 

...等同于:

fn into_iterator(myvec: &Vec<Foo>) -> Box<Iterator<Item = &Foo> + 'static> 

现在一辈子省音规则踢, “连接”两个使用寿命插槽,以使上述代码相当于:

fn into_iterator<'a>(myvec: &'a Vec<Foo>) -> Box<Iterator<Item = &'a Foo> + 'static> 

但是类型Iter<'a, Foo>(具体的迭代器类型为Vec<Foo>)显然不满足绑定的'static(因为它借用了Vec<Foo>)!因此,我们必须告诉我们不希望通过指定自己的一生约束绑定的默认'static编译:

fn into_iterator<'a>(myvec: &'a Vec<Foo>) -> Box<Iterator<Item = &Foo> + 'a> 

现在编译器知道特质对象仅适用于寿命'a。请注意,我们不明确需要注释关联的Item类型的生命周期!终身安全规则会照顾到这一点。

+0

哦,当然!我完全忘了它不是关于Foo,而是迭代器本身;我第一次以为终身限制是在一个结构...感谢澄清这一点! – torkleyy

相关问题