Iterator::cycle în Rust

Repetă la nesfârșit elementele iteratorului: după ultimul, o ia de la capăt.

Sintaxă
fn cycle(self) -> Cycle<Self>
where Self: Clone

Ce face Iterator::cycle

cycle() produce elementele sursei, apoi le reia de la început, la infinit. Pentru a putea relua, iteratorul trebuie să implementeze Clone (iteratorii de vectori, slice-uri și intervale îl au). Dacă sursa este goală, și cycle este gol.

Fiind infinit, se folosește împreună cu take(n), cu zip (care se oprește la celălalt șir) sau într-o buclă cu break. Este util pentru alternări: ture prin rotație, culori alternante pe rânduri, jucători care mută pe rând.

Ce returnează

Un iterator infinit Cycle.

Exemple

Exemplul 1: Sarcini împărțite prin rotație

zip se oprește când se termină sarcinile, deci ciclul infinit al persoanelor nu e o problemă.

fn main() {
    let echipa = ["Ana", "Mihai", "Ioana"];
    let sarcini = ["vase", "aspirat", "gunoi", "cumpărături", "rufe"];
    for (sarcina, cine) in sarcini.iter().zip(echipa.iter().cycle()) {
        println!("{sarcina:12} -> {cine}");
    }
}

Rezultat

vase         -> Ana
aspirat      -> Mihai
gunoi        -> Ioana
cumpărături  -> Ana
rufe         -> Mihai

Exemplul 2: Rânduri alternante și zilele următoare

fn main() {
    let stiluri = ["alb", "gri"].iter().cycle();
    for (rand, stil) in (1..=5).zip(stiluri) {
        println!("rândul {rand}: fundal {stil}");
    }

    let zile = ["L", "Ma", "Mi", "J", "V", "S", "D"];
    let urmatoarele_10: Vec<&str> = zile.iter().cycle().skip(4).take(10).copied().collect();
    println!("{}", urmatoarele_10.join(" "));
}

Rezultat

rândul 1: fundal alb
rândul 2: fundal gri
rândul 3: fundal alb
rândul 4: fundal gri
rândul 5: fundal alb
V S D L Ma Mi J V S D

Greșeli frecvente

  • Colectezi sau numeri un cycle() fără limită: programul nu se mai termină. Adaugă take(n).
  • Apelezi cycle() pe un iterator care nu implementează Clone (de exemplu stdin().lines()): nu compilează. Colectează întâi într-un vector.

Comenzi înrudite

  • iter::repeat: Creează un iterator care repetă la nesfârșit aceeași valoare; de obicei urmat de take(n).
  • Iterator::take: take(n) produce cel mult primele n elemente; skip(n) sare peste primele n și produce restul.
  • Iterator::zip: Parcurge două șiruri în paralel și produce perechi (a, b); se oprește când se termină cel mai scurt.
  • Vec::rotate_left: Rotește elementele spre stânga: primele mid elemente trec la final, în aceeași ordine. rotate_right face invers.