2015-07-15 8 views
10

Quando una funzione accetta una serie di valori come parametro, è considerato buono stile accettare uno Iterator<T> anziché Vec<T>?Prendere un `Iterator` invece di` Vec` quando possibile?

In questo modo, il chiamante può decidere autonomamente come è memorizzata la serie (all'interno di uno Vec, uno [T; N] o qualsiasi altra cosa, in realtà dovrebbe essere possibile un Option<T>!). Inoltre, questo elimina la necessità di convertire qualsiasi cosa tu abbia in un Vec, e inoltre, dopo aver applicato alcuni modificatori Iterator, non è necessario il numero .collect()! Quindi dovrebbe anche essere più veloce!

Mi manca qualcosa o è così che dovrebbe essere fatto?

risposta

11

Tale funzione, come descritta, generalmente richiede un IntoIterator<Item = T>; quindi può accettare sia Iterator<T> sia Vec<T> come input.

Questo può essere combinato anche con altre tecniche; per esempio, questo metodo concat accetterà una &[&str] (e quindi &Vec<&str> da auto deref/coercizione ref), &[String] (e quindi &Vec<String>), un &str iteratore, un String iteratore, eccetera:

use std::borrow::Borrow; 

fn concat<T: Borrow<str>, Iter: IntoIterator<Item = T>>(iter: Iter) -> String { 
    iter.into_iter() // -> impl Iterator<Item = T> 
     .map(|s| s.borrow()) // -> impl Iterator<Item = &str> 
     .collect() // -> String 
} 

(Questo specifico esempio sarebbe in genere più adatto a SliceConcatExt, perché è in grado di calcolare per quanto tempo il risultato finale sarà in primo piano e quindi allocare la giusta lunghezza di stringa tutto in una volta, ma è solo una dimostrazione del concetto e di come molteplici tecniche di fantasia può essere combinato.)

Problemi correlati