2015-08-21 16 views
5

Wprowadziłem cechę Iterator dla kilku struktur i napotkałem pewne problemy. Dlaczego implementacja Iterator dla Rows pokazuje błąd? Oto link: link to playgroundDożywotni problem z implementacją Iteratora

Zasadniczo dlaczego to nie działa?

struct Stripe<'a> { 
    cells: &'a [u32], 
} 

struct Rows<'a> { 
    foo: &'a Foo, 
    vec: Vec<u32>, 
    first: bool, 
} 

impl<'a> std::iter::Iterator for Rows<'a> { 
    type Item = Stripe<'a>; 
    fn next(&mut self) -> Option<Stripe<'a>> { 
     if self.first { 
      self.first = false; 
      Some(
       Stripe { 
        cells: &self.vec[0..1], 
       } 
      ) 
     } else { 
      None 
     } 
    } 
} 
+0

Ok, dzięki, postaram – Spiderpig

+2

Upewnij się, że Twój kod to [MCVE] (/ help/mcve). Powinieneś być w stanie usunąć cały puch, który nie jest bezpośrednio związany z twoim pytaniem. – Shepmaster

+1

Więc zmniejszyłem mój kod, czy to wystarczająco czytelne? – Spiderpig

Odpowiedz

2

Żywotność 'a w rodzaju odnosi się tylko do jednego pola typu. Odniesienia, które powracasz, nie mają nic wspólnego z tym życiem. Cecha Iterator nie pozwala na powrót wcieleń do samego obiektu iteratora. To wymagałoby dodania nowego okresu użytkowania do funkcji next.

Proponuję utworzyć RowsIterator typ z odniesieniem do obiektu Rows i obsłużyć rzeczy iterator specyficzne tam:

struct Stripe<'a> { 
    cells: &'a [u32], 
} 

struct Rows { 
    vec: Vec<u32>, 
} 

struct RowsIter<'a> { 
    rows: &'a Rows, 
    first: bool, 
} 

impl<'a> std::iter::Iterator for RowsIter<'a> { 
    type Item = Stripe<'a>; 
    fn next(&mut self) -> Option<Stripe<'a>> { 
     if self.first { 
      self.first = false; 
      Some(
       Stripe { 
        cells: &self.rows.vec[0..1], 
       } 
      ) 
     } else { 
      None 
     } 
    } 
} 

Pełny przykład w playground

+0

Dzięki, twoje wyjaśnienie pomogło. Ale wciąż mam problem, ponieważ potrzebuję typu Foo, ale myślę, że sam sobie poradzę. – Spiderpig

+0

Dziękuję za pełny przykład, nie zauważyłem tego na początku. – Spiderpig

+0

można faktycznie oddzielić okresy życia od 'foo' odniesienia' Wierszy' i okresu życia 'wierszy' odniesienia' RowsIter', ale najprawdopodobniej nie potrzebujesz tego. Po prostu użyłem tego samego okresu życia dla obu w pełnym przykładzie. Zobacz tutaj przykład, gdzie okresy życia są różne: http://is.gd/hb09uj –