2017-02-03 2 views
4

Ich bin eine Schließung auf den Iterator anwenden und ich möchte stabil, also möchte ich eine Box Iterator zurückgeben. Der offensichtliche Weg, dies zu tun, ist folgende:Warum wird Box <Iterator <Item = &Foo> + 'a> benötigt?

struct Foo; 

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

Dies schlägt fehl, da der borrow checker das entsprechende Lebensdauern nicht ableiten kann.

Nach einigen Recherchen habe ich Correct way to return an Iterator? gefunden, was mich + 'a zum Hinzufügen gebracht:

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

Aber ich verstehe nicht

  • Was das bedeutet
  • Und warum es benötigt hier

Antwort

8

Es gibt eine Sache, die leicht übersehen wird: Wenn Sie ein Merkmal haben Foo und Sie möchten ein Boxed-Objekt Objekt Box<Foo> haben, fügt der Compiler automatisch eine 'static Lebensdauer gebunden (wie in RFC 599 angegeben). Dies bedeutet, dass Box<Foo> und Box<Foo + 'static> gleichwertig sind!

In Ihrem Fall fügt der Compiler automatisch die statische so gebunden, dass diese ...

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

... ist äquivalent zu:

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

Jetzt Regeln Lebensdauer elision treten in und "Verbinden" Sie die beiden Lebensdauer-Steckplätze, so dass der obige Code entspricht:

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

Aber der Typ Iter<'a, Foo> (der spezifische Iteratortyp für Vec<Foo>) erfüllt offensichtlich nicht die Grenze 'static (weil es das Vec<Foo> ausborgt)! Also müssen wir den Compiler sagen, dass wir nicht wollen, die Standard-'static gebunden durch unsere eigene Lebensdauer Angabe gebunden:

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

Jetzt ist der Compiler weiß, dass das Merkmal Objekt für die gesamte Lebensdauer 'a nur gültig ist. Beachten Sie, dass die Lebensdauer des zugehörigen Typs Item nicht explizit mit Anmerkungen versehen werden muss! Lebenslange Regeln sorgen dafür.

+0

Oh natürlich! Ich habe völlig vergessen, dass es nicht um Foo geht, sondern um den Iterator selbst; Ich dachte zuerst, dass die Lebenszeitgrenze auf einer Struktur lag ... Danke, dass du das erklärst! – torkleyy