loop, break și continue în Rust

loop repetă un bloc la nesfârșit până la un break; break poate returna o valoare, iar continue sare la pasul următor al buclei.

Sintaxă
loop {
    ...
    if gata { break; }
}
let x = loop { break valoare; };
'eticheta: loop { ... break 'eticheta; }
continue;              // sare la pasul următor

Ce face loop, break și continue

loop repetă blocul până când întâlnește break. Este bucla potrivită când condiția de oprire se află în mijlocul corpului, de exemplu „citește până primești o valoare bună”.

break oprește bucla. În loop, break valoare face ca bucla să fie o expresie cu acea valoare: let rezultat = loop { ... break x; };. continue abandonează pasul curent și trece la următorul. Ambele funcționează și în for și while.

Când ai bucle una în alta, break oprește doar bucla cea mai interioară. Ca să oprești o buclă exterioară, îi pui o etichetă care începe cu apostrof ('cautare: for ...) și scrii break 'cautare; sau continue 'cautare;.

Exemple

Exemplul 1: loop care returnează o valoare

Bucla încearcă numere până găsește primul divizibil cu 7 și cu 11, apoi îl returnează cu break n.

fn main() {
    let mut n = 100;
    let gasit = loop {
        if n % 7 == 0 && n % 11 == 0 {
            break n;
        }
        n += 1;
    };
    println!("Primul număr ≥ 100 divizibil cu 7 și 11: {gasit}");
}

Rezultat

Primul număr ≥ 100 divizibil cu 7 și 11: 154

Exemplul 2: continue pentru a sări peste elemente

Comenzile anulate sunt sărite cu continue; restul sunt adunate. La o comandă invalidă (sumă negativă), break oprește prelucrarea.

fn main() {
    let comenzi = [("C1", 120), ("C2", 0), ("C3", 75), ("C4", -10), ("C5", 300)];
    let mut total = 0;
    for (cod, suma) in comenzi {
        if suma == 0 {
            println!("{cod}: anulată, o sar");
            continue;
        }
        if suma < 0 {
            println!("{cod}: sumă invalidă, mă opresc");
            break;
        }
        total += suma;
    }
    println!("Total încasat: {total} lei");
}

Rezultat

C2: anulată, o sar
C4: sumă invalidă, mă opresc
Total încasat: 195 lei

Exemplul 3: Etichete pentru bucle imbricate

break 'cautare oprește ambele bucle imediat ce s-a găsit locul liber. Fără etichetă, s-ar opri doar bucla interioară.

fn main() {
    let sala = [
        ['X', 'X', 'X', 'X'],
        ['X', 'X', '.', 'X'],
        ['.', 'X', '.', '.'],
    ];
    let mut loc = None;
    'cautare: for (r, rand) in sala.iter().enumerate() {
        for (c, &scaun) in rand.iter().enumerate() {
            if scaun == '.' {
                loc = Some((r + 1, c + 1));
                break 'cautare;
            }
        }
    }
    println!("Primul loc liber (rând, scaun): {loc:?}");
}

Rezultat

Primul loc liber (rând, scaun): Some((2, 3))

Greșeli frecvente

  • Uiți condiția de oprire într-un loop: programul rulează la nesfârșit. Asigură-te că fiecare drum prin buclă poate ajunge la un break sau return.
  • Folosești break valoare într-un for sau while. Doar loop poate returna o valoare prin break; în celelalte bucle salvează valoarea într-o variabilă.
  • Scrii loop + if + break la început când condiția este cunoscută dinainte. while conditie exprimă același lucru mai clar.

Comenzi înrudite

  • for … in: Parcurge pe rând fiecare element al unui interval, al unei colecții sau al unui iterator.
  • while: Repetă un bloc de cod cât timp o condiție bool rămâne adevărată; condiția este verificată înainte de fiecare pas.
  • while let: Repetă un bloc cât timp o valoare se potrivește cu un tipar, de exemplu cât timp pop() mai returnează Some.
  • if și else: Execută un bloc de cod doar dacă o condiție bool este adevărată. În Rust, if este o expresie: poate da o valoare.