Ce face iter::successors
successors(Some(primul), |x| ...) produce întâi primul, apoi rezultatul funcției aplicate pe el, apoi rezultatul aplicat pe acela și așa mai departe. Funcția primește o referință la elementul curent și returnează Some(urmatorul) sau None pentru oprire. Dacă primul argument este None, iteratorul este gol.
Este potrivit pentru puteri, dobânzi compuse, împărțiri repetate, șirul lui Collatz. Cu checked_mul / checked_add în funcție, șirul se oprește singur înainte de depășire.
Parametri
| Parametru | Descriere |
|---|---|
first |
Primul element, în Some (sau None pentru un iterator gol). |
succ |
Funcția care calculează următorul element din &curent. |
Ce returnează
Un iterator Successors.
Exemple
Exemplul 1: Puterile lui 2 până la depășire
checked_mul dă None când rezultatul nu mai încape în u16, deci șirul se oprește singur.
use std::iter::successors;
fn main() {
let puteri: Vec<u16> = successors(Some(1u16), |&x| x.checked_mul(2)).collect();
println!("{} puteri: {:?}", puteri.len(), puteri);
}
Rezultat
16 puteri: [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768]
Exemplul 2: Economii cu dobândă de 5% pe an
use std::iter::successors;
fn main() {
let ani = successors(Some(1000.0_f64), |s| Some(s * 1.05)).take(6);
for (an, suma) in ani.enumerate() {
println!("anul {an}: {suma:.2} lei");
}
}
Rezultat
anul 0: 1000.00 lei
anul 1: 1050.00 lei
anul 2: 1102.50 lei
anul 3: 1157.62 lei
anul 4: 1215.51 lei
anul 5: 1276.28 lei
Exemplul 3: Șirul lui Collatz și cifrele unui număr
use std::iter::successors;
fn main() {
let collatz: Vec<u64> = successors(Some(6u64), |&n| match n {
1 => None,
n if n % 2 == 0 => Some(n / 2),
n => Some(3 * n + 1),
})
.collect();
println!("{:?}", collatz);
let cifre = successors(Some(2026u32), |&n| (n >= 10).then_some(n / 10)).count();
println!("2026 are {cifre} cifre");
}
Rezultat
[6, 3, 10, 5, 16, 8, 4, 2, 1]
2026 are 4 cifre
Greșeli frecvente
- Funcția returnează mereu
Someși apelezicollect: iteratorul e infinit. Adaugătakesau o condiție de oprire. - Uiți că primul argument e un
Option:successors(1, ..)nu compilează; scriesuccessors(Some(1), ..).
Comenzi înrudite
iter::from_fn: Creează un iterator dintr-un closure: fiecare apel al closure-ului dă următorul element, iar None oprește iteratorul.Iterator::scan: Ca fold, dar produce câte un rezultat după fiecare element: o stare actualizată pas cu pas, de exemplu un total cumulat.Iterator::take_while: take_while dă elemente cât timp condiția e adevărată și se oprește la primul care nu o îndeplinește; skip_while sare până atunci.Iterator::fold: Combină toate elementele într-o singură valoare, pornind de la o valoare inițială și aplicând o funcție pas cu pas.