2015-08-21 17 views
5

Stavo implementando il tratto Iterator per diverse strutture e ho riscontrato alcuni problemi. Perché l'implementazione di Iterator per Rows mostra un errore? Ecco un collegamento: link to playgroundProblema a vita durante l'implementazione di Iterator

Fondamentalmente perché questo non funziona?

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, grazie, cercherò – Spiderpig

+2

E assicurati che il tuo codice sia un [MCVE] (/ help/mcve). Dovresti essere in grado di rimuovere tutta la peluria che non è * direttamente * rilevante per la tua domanda. – Shepmaster

+1

Quindi ho riutilizzato il mio codice, è abbastanza leggibile? – Spiderpig

risposta

2

La durata 'a nel tipo riferisce ad un solo campo di tipo. I riferimenti che stai restituendo non hanno nulla a che fare con quella vita. Il tratto Iterator non consente di restituire vite nell'oggetto iteratore stesso. Ciò richiederebbe l'aggiunta di una nuova durata alla funzione next.

Vi suggerisco di creare un tipo RowsIterator con un riferimento al vostro Rows oggetto e gestire la roba-specific iteratore in là:

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 
     } 
    } 
} 

esempio completo nella playground

+0

Grazie, la tua spiegazione ha aiutato. Ma ho ancora un problema, perché in realtà ho bisogno del tipo Foo, ma credo di poterlo fare da solo. – Spiderpig

+0

Grazie per l'esempio completo, non l'ho notato all'inizio. – Spiderpig

+0

si potrebbe effettivamente separare la durata del riferimento 'foo' di' Righe' e la durata del riferimento 'rows' di' RowsIter', ma molto probabilmente non è necessario. Ho semplicemente usato la stessa vita per entrambi nell'esempio completo. Vedi qui per un esempio in cui le durate sono diverse: http://is.gd/hb09uj –