Ce face FromIterator
FromIterator<A> spune că un tip poate fi construit dintr-un șir de valori de tip A. it.collect::<X>() este doar o formă comodă pentru X::from_iter(it). Biblioteca standard îl implementează pentru toate colecțiile, pentru String, Box<[T]>, Result, Option, () și altele.
Poți apela și direct Vec::from_iter(1..4) sau String::from_iter(['a', 'b']); trait-ul este în preludiu, deci nu are nevoie de use. Implementându-l pentru un tip propriu, îl faci compatibil cu collect().
Ce returnează
from_iter returnează o valoare nouă de tipul Self.
Exemple
Exemplul 1: from_iter apelat direct
use std::collections::VecDeque;
fn main() {
let v = Vec::from_iter(1..=4);
let s = String::from_iter(['R', 'u', 's', 't']);
let c = VecDeque::from_iter(["Ana", "Mihai"]);
println!("{:?} {:?} {:?}", v, s, c);
}
Rezultat
[1, 2, 3, 4] "Rust" ["Ana", "Mihai"]
Exemplul 2: collect() într-un tip propriu
Implementăm FromIterator<i64> pentru o structură de statistici. De acum, orice iterator de i64 poate fi colectat în ea.
struct Statistici {
numar: usize,
suma: i64,
minim: i64,
maxim: i64,
}
impl FromIterator<i64> for Statistici {
fn from_iter<I: IntoIterator<Item = i64>>(iter: I) -> Self {
let mut s = Statistici { numar: 0, suma: 0, minim: i64::MAX, maxim: i64::MIN };
for x in iter {
s.numar += 1;
s.suma += x;
s.minim = s.minim.min(x);
s.maxim = s.maxim.max(x);
}
s
}
}
fn main() {
let temperaturi = [4, -2, 9, 7, 12];
let s: Statistici = temperaturi.into_iter().collect();
println!("{} valori, suma {}, între {} și {}", s.numar, s.suma, s.minim, s.maxim);
let pare: Statistici = (1..=10).filter(|x| x % 2 == 0).collect();
println!("pare: {} valori, suma {}", pare.numar, pare.suma);
}
Rezultat
5 valori, suma 30, între -2 și 12
pare: 5 valori, suma 30
Greșeli frecvente
- Colectezi într-un tip pentru care nu există
FromIteratorcu acel tip de element: a value of type `X` cannot be built from an iterator over elements of type `Y`. Transformă elementele întâi (map,copied) sau implementează trait-ul. - Confunzi
FromIteratorcuFrom:Vec::from([1, 2])foloseșteFrom(din tablou),Vec::from_iter(..)primește orice iterator.
Comenzi înrudite
Iterator::collect: Consumă iteratorul și adună valorile într-o colecție: Vec, String, HashMap, HashSet, chiar Result sau Option.IntoIterator: Trait-ul tipurilor care pot fi transformate într-un iterator; este ce folosește bucla for pentru a parcurge o valoare.Iterator: Trait-ul care descrie orice șir de valori produse pe rând: next() dă următoarea valoare, sau None la final.