2015-07-13 16 views
7

Trovo strano che Iterator::take_while diventi proprietario dell'iteratore. Sembra una funzione utile per poter prendere i primi elementi x che soddisfano alcune funzioni ma che comunque lasciano il resto degli elementi disponibili nell'iteratore originale.Perché Iterator :: take_while diventa proprietario dell'iteratore?

Capisco che questo non è compatibile con un'implementazione lenta di take_while, ma si sente ancora utile. Questo è stato appena giudicato non abbastanza utile da includere nella libreria standard, o c'è qualche altro problema che non vedo?

risposta

9

Tutti gli adattatori iteratori prendono l'iteratore originale in base al valore per motivi di efficienza. Se si desidera mantenere l'accesso all'iteratore originale, è possibile utilizzare by_ref. Questo introduce un livello di indirezione, ma il programmatore sceglie di optare per il lavoro extra quando è necessaria la funzione:

fn main() { 
    let v = [1, 2, 3, 4, 5, 6, 7, 8]; 
    let mut i1 = v.iter(); 
    for z in i1.by_ref().take_while(|&&v| v < 4) { 
     println!("Take While: {}", z); 
    } 

    for z in i1 { 
     println!("Rest: {}", z); 
    } 
} 

ha l'uscita

Take While: 1 
Take While: 2 
Take While: 3 
Rest: 5 
Rest: 6 
Rest: 7 
Rest: 8 

Avete notato che 4 mancava? Questo perché una volta che take_while preleva un valore e decide di non utilizzarlo, non c'è nulla da cui "rimetterlo". Per rimetterlo, è necessario optare per più spazio di archiviazione e lentezza di di quanto sia sempre necessario.

Ho utilizzato il itertools crate per gestire casi come questo, in particolare take_while_ref.