Ricerca…
Sintassi
loop { block } // infinito loop
while condition { block }
mentre lascia pattern = expr { block }
per il modello in expr { block } // expr deve implementare IntoIterator
continua // salta alla fine del corpo del ciclo, iniziando una nuova iterazione, se necessario
pausa // interrompi il ciclo
' label : loop { block }
' label : while condition { block }
' label : while let pattern = expr { block }
' label : per pattern in expr { block }
continua ' label // salta alla fine dell'etichetta etichettata con il corpo del loop, avviando una nuova iterazione, se necessario
break ' label // interrompe l'etichetta etichettata loop
Nozioni di base
Ci sono 4 costrutti di looping in Rust. Tutti gli esempi di seguito producono lo stesso risultato.
Cicli infiniti
let mut x = 0;
loop {
if x > 3 { break; }
println!("{}", x);
x += 1;
}
Mentre cicli
let mut x = 0;
while x <= 3 {
println!("{}", x);
x += 1;
}
Vedi anche: Qual è la differenza tra loop e while true ?
Cicli combinati con schema
Questi sono a volte noti come while let cicli per brevità.
let mut x = Some(0);
while let Some(v) = x {
println!("{}", v);
x = if v < 3 { Some(v + 1) }
else { None };
}
Questo è equivalente a una match all'interno di un blocco di loop :
let mut x = Some(0);
loop {
match x {
Some(v) => {
println!("{}", v);
x = if v < 3 { Some(v + 1) }
else { None };
}
_ => break,
}
}
Per loop
In Rust, for loop può essere utilizzato solo con un oggetto "iterable" (cioè dovrebbe implementare IntoIterator ).
for x in 0..4 {
println!("{}", x);
}
Questo è equivalente al seguente snippet che coinvolge while let :
let mut iter = (0..4).into_iter();
while let Some(v) = iter.next() {
println!("{}", v);
}
Nota: 0..4 restituisce un oggetto Range che implementa già il tratto Iterator . Pertanto into_iter() non è necessaria, ma è tenuto solo per illustrare ciò che for fa. Per un approfondimento, vedi la documentazione ufficiale for Loops e IntoIterator .
Vedi anche: Iterators
Maggiori informazioni sui loop For
Come accennato in Nozioni di base, possiamo usare tutto ciò che implementa IntoIterator con il ciclo for :
let vector = vec!["foo", "bar", "baz"]; // vectors implement IntoIterator
for val in vector {
println!("{}", val);
}
Uscita prevista:
foo
bar
baz
Si noti che l'iterazione sul vector in questo modo la consuma (dopo il ciclo for , il vector non può essere riutilizzato). Questo perché IntoIterator::into_iter sposta self .
IntoIterator è anche implementato da &Vec<T> e &mut Vec<T> (producendo valori con tipi &T e &mut T rispettivamente) in modo da poter impedire lo spostamento del vector semplicemente passandolo per riferimento:
let vector = vec!["foo", "bar", "baz"];
for val in &vector {
println!("{}", val);
}
println!("{:?}", vector);
Si noti che val è di tipo &&str , poiché vector è di tipo Vec<&str> .
Controllo del ciclo
Tutti i costrutti di ciclo consentono l'uso di istruzioni break e continue . Influiscono sul ciclo immediatamente circostante (più interno).
Basic Loop Control
break termina il ciclo:
for x in 0..5 {
if x > 2 { break; }
println!("{}", x);
}
Produzione 0
1
2
continue termina l'iterazione corrente in anticipo
for x in 0..5 {
if x < 2 { continue; }
println!("{}", x);
}
Produzione 2
3
4
Controllo avanzato del ciclo
Ora, supponiamo di avere cicli annidati e vogliamo break verso il ciclo esterno. Quindi, possiamo usare le etichette di loop per specificare a quale ciclo si applica una break o continue . Nell'esempio seguente, 'outer è l'etichetta data al loop esterno.
'outer: for i in 0..4 {
for j in i..i+2 {
println!("{} {}", i, j);
if i > 1 {
continue 'outer;
}
}
println!("--");
}
Produzione 0 0
0 1
--
1 1
1 2
--
2 2
3 3
Per i > 1 , il ciclo interno è stato iterato una sola volta e -- non è stato stampato.
Nota: non confondere un'etichetta di loop con una variabile a vita. Le variabili a vita si verificano solo accanto a un & o come parametro generico all'interno di <> .