2017-02-03 85 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

相關問題