2017-02-03 39 views
4

イテレータにクロージャを適用していますので、安定したものを使用したいので、ボックス化されたIteratorを返したいと思います。これを行う明白な方法は次のとおりです。Box <Iterator <Item = &Foo> + 'a>はなぜ必要ですか?

struct Foo; 

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

これは、借用チェッカーが適切な有効期間を推論できないために失敗します。

いくつかの研究の後、私は+ 'aを追加することに私をもたらしたCorrect way to return an Iterator?を、見つけた:

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

しかし、私は、これは

  • そして、なぜそれが何

    • を理解していませんここに必要です
  • 答えて

    8

    簡単に見落とされることが1つあります:特性がFooで、ボックス化された特性オブジェクトBox<Foo>を使用したい場合、コンパイラは有効期限が(RFC 599で指定されているように)'staticに自動的に追加されます。つまり、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> 
    

    しかしタイプ:上記のコードと等価であるように、2ライフタイムスロットを「接続」 (Vec<Foo>の特定のイテレータタイプ)Iter<'a, Foo>は、明らかに(Vec<Foo>を借りているため)バインド'staticを満たしていません!だから我々は、我々がバインド私たち自身の寿命を指定することにより、拘束デフォルト'staticを望んでいないコンパイラに指示する必要があります。

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

    今コンパイラが形質オブジェクトが寿命'aにのみ有効であることを知っています。関連するItemタイプの生存期間を明示的に注釈する必要はありません。永遠のエリシオンルールがそれを処理します。

    +0

    もちろん!私はそれがFooについてではなくIteratorそのものではないことを完全に忘れてしまった。私は最初に構造体上の生存時間を考えました...これを明確にしてくれてありがとう! – torkleyy

    関連する問題