Ce face Iterator::cloned
v.iter() produce referințe. Când ai nevoie de valori proprii (de exemplu ca să colectezi un Vec<i32>, nu Vec<&i32>), adaugă .copied() sau .cloned().
copied() merge doar pentru tipuri Copy (numere, char, bool, &str) și e o copiere ieftină de biți. cloned() merge pentru orice tip Clone, inclusiv String și Vec, dar poate aloca memorie. Preferă copied când merge: îți arată clar că e ieftin.
Există și pe Option: v.iter().max().copied() transformă Option<&i32> în Option<i32>. Ca toate adaptoarele, este leneș: nu face nimic până când iteratorul nu este consumat (de for, collect, sum, count etc.).
Ce returnează
Un iterator Copied sau Cloned care produce T.
Exemple
Exemplul 1: Din &i32 în i32
fn main() {
let note = vec![7, 9, 10, 6];
let referinte: Vec<&i32> = note.iter().collect();
let valori: Vec<i32> = note.iter().copied().collect();
println!("{:?} {:?}", referinte, valori);
let maxim: Option<i32> = note.iter().max().copied();
println!("maxim: {:?}", maxim);
}
Rezultat
[7, 9, 10, 6] [7, 9, 10, 6]
maxim: Some(10)
Exemplul 2: cloned pentru String-uri
String nu este Copy, deci copied() nu compilează; cloned() face câte o copie a fiecărui text.
fn main() {
let elevi = vec![String::from("Ana"), String::from("Mihai"), String::from("Ioana")];
let mut sortati: Vec<String> = elevi.iter().cloned().collect();
sortati.sort();
println!("originalul: {:?}", elevi);
println!("copia sortată: {:?}", sortati);
}
Rezultat
originalul: ["Ana", "Mihai", "Ioana"]
copia sortată: ["Ana", "Ioana", "Mihai"]
Greșeli frecvente
- Folosești
copied()pe referințe laString: the trait bound `String: Copy` is not satisfied. Foloseștecloned(). - Clonezi la începutul unui lanț lung, înainte de
filter: clonezi și elementele pe care apoi le arunci. Punecloned()cât mai la final.
Comenzi înrudite
Iterator::map: Transformă fiecare valoare a iteratorului cu o funcție și dă un iterator cu rezultatele; nu calculează nimic până la consumare.Iterator::collect: Consumă iteratorul și adună valorile într-o colecție: Vec, String, HashMap, HashSet, chiar Result sau Option.Vec::to_vec: Creează un Vec nou, cu copii ale elementelor dintr-un slice: dintr-un tablou, dintr-o bucată de vector sau dintr-un &[T].Vec::iter: Cele trei moduri de a parcurge un vector: iter dă referințe, iter_mut dă referințe mutabile, into_iter dă elementele.