Ce face iter::from_fn
std::iter::from_fn(|| ...) este cel mai rapid mod de a face un iterator propriu fără să scrii o structură și un impl Iterator. Starea (contoare, poziții) stă în variabilele capturate de closure, de obicei cu move. Closure-ul returnează Some(valoare) pentru fiecare element și None când s-a terminat.
Dacă closure-ul nu returnează niciodată None, iteratorul este infinit și trebuie limitat cu take. Pentru șiruri în care fiecare element se calculează din cel dinainte, successors e mai potrivit.
Parametri
| Parametru | Descriere |
|---|---|
f |
Closure FnMut() -> Option<T>, apelat pentru fiecare element. |
Ce returnează
Un iterator FromFn.
Exemple
Exemplul 1: Numerotare pentru bonuri
use std::iter::from_fn;
fn main() {
let mut numar = 1000;
let bonuri = from_fn(move || {
numar += 1;
if numar <= 1005 { Some(format!("BON-{numar}")) } else { None }
});
println!("{:?}", bonuri.collect::<Vec<_>>());
}
Rezultat
["BON-1001", "BON-1002", "BON-1003", "BON-1004", "BON-1005"]
Exemplul 2: Șirul lui Fibonacci
Iteratorul este infinit; take_while îl oprește.
use std::iter::from_fn;
fn main() {
let (mut a, mut b) = (0u64, 1u64);
let fibonacci = from_fn(move || {
let urmator = a;
(a, b) = (b, a + b);
Some(urmator)
});
let sub_100: Vec<u64> = fibonacci.take_while(|&x| x < 100).collect();
println!("{:?}", sub_100);
}
Rezultat
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
Exemplul 3: Bucăți de text de lungime fixă
use std::iter::from_fn;
fn main() {
let mut rest = "RO49AAAA1B31007593840000";
let grupuri: Vec<&str> = from_fn(|| {
if rest.is_empty() {
return None;
}
let (bucata, r) = rest.split_at(rest.len().min(4));
rest = r;
Some(bucata)
})
.collect();
println!("{}", grupuri.join(" "));
}
Rezultat
RO49 AAAA 1B31 0075 9384 0000
Greșeli frecvente
- Uiți
movecând returnezi iteratorul dintr-o funcție: closure-ul împrumută variabile locale care dispar (closure may outlive the current function). - Closure-ul nu returnează niciodată
Noneși apoi apelezicollect: programul nu se termină. Limitează cutakesautake_while.
Comenzi înrudite
iter::successors: Creează un șir în care fiecare element se calculează din cel dinainte; se oprește când funcția returnează None.Iterator: Trait-ul care descrie orice șir de valori produse pe rând: next() dă următoarea valoare, sau None la final.Fn, FnMut și FnOnce: Cele trei trait-uri ale closure-urilor: Fn doar citește ce a capturat, FnMut modifică, FnOnce consumă și poate fi apelat o singură dată.Iterator::take: take(n) produce cel mult primele n elemente; skip(n) sare peste primele n și produce restul.