Zoeken…
Syntaxis
loop { block } // oneindige lus
terwijl conditie { block }
terwijl let pattern = expr { block }
voor patroon in expr { block } // expr moet IntoIterator implementeren
ga door // spring naar het einde van de lus, start zo nodig een nieuwe iteratie
break // stop de lus
' label : loop { block }
' label : while condition { block }
' label : while let pattern = expr { block }
' label : voor patroon in expr { block }
ga door ' label // spring naar het einde van het lusvormige label , begin zo nodig met een nieuwe iteratie
break ' label // stop de lus gelabelde label
Basics
Er zijn 4 lusconstructies in Rust. Alle onderstaande voorbeelden produceren dezelfde uitvoer.
Oneindige lussen
let mut x = 0;
loop {
if x > 3 { break; }
println!("{}", x);
x += 1;
}
While Loops
let mut x = 0;
while x <= 3 {
println!("{}", x);
x += 1;
}
Zie ook: Wat is het verschil tussen loop
en while true
?
Bijpassend patroon tijdens loops
Deze staan soms bekend als ' while let
loops' voor beknoptheid.
let mut x = Some(0);
while let Some(v) = x {
println!("{}", v);
x = if v < 3 { Some(v + 1) }
else { None };
}
Dit komt overeen met een match
in een loop
:
let mut x = Some(0);
loop {
match x {
Some(v) => {
println!("{}", v);
x = if v < 3 { Some(v + 1) }
else { None };
}
_ => break,
}
}
Voor lussen
In Rust kan for
lus alleen worden gebruikt met een "iterabel" object (dwz het moet IntoIterator
implementeren).
for x in 0..4 {
println!("{}", x);
}
Dit komt overeen met het volgende fragment waarbij while let
:
let mut iter = (0..4).into_iter();
while let Some(v) = iter.next() {
println!("{}", v);
}
Opmerking: 0..4
retourneert een Range
object dat de Iterator
eigenschap al implementeert. Daarom into_iter()
is overbodig, maar blijft gewoon om te illustreren wat for
doet. Zie de officiële documenten for
Loops en IntoIterator
voor een diepgaande blik.
Zie ook: Iterators
Meer over For Loops
Zoals vermeld in de basis, kunnen we alles gebruiken dat IntoIterator
implementeert met de for
lus:
let vector = vec!["foo", "bar", "baz"]; // vectors implement IntoIterator
for val in vector {
println!("{}", val);
}
Verwachte resultaten:
foo
bar
baz
Merk op dat iteratie over vector
op deze manier het verbruikt (na de for
lus kan vector
niet meer worden gebruikt). Dit komt omdat IntoIterator::into_iter
self
verplaatst .
IntoIterator
wordt ook geïmplementeerd door &Vec<T>
en &mut Vec<T>
(levert waarden op met respectievelijk de types &T
en &mut T
), zodat u de verplaatsing van de vector
kunt voorkomen door deze eenvoudigweg als referentie door te geven:
let vector = vec!["foo", "bar", "baz"];
for val in &vector {
println!("{}", val);
}
println!("{:?}", vector);
Merk op dat val
van het type &&str
, omdat vector
van het type Vec<&str>
.
Loop Control
Alle lusconstructies maken het gebruik van break
en continue
statements mogelijk. Ze beïnvloeden de onmiddellijk omringende (binnenste) lus.
Basic Loop Control
break
beëindigt de lus:
for x in 0..5 {
if x > 2 { break; }
println!("{}", x);
}
uitgang 0
1
2
continue
beëindigt de huidige iteratie vroeg
for x in 0..5 {
if x < 2 { continue; }
println!("{}", x);
}
uitgang 2
3
4
Geavanceerde Loop Control
Stel nu dat we geneste lussen hebben en uit willen break
naar de buitenste lus. Vervolgens kunnen we luslabels gebruiken om aan te geven op welke lus een break
of continue
toepassing is. In het volgende voorbeeld is 'outer
het label dat aan de buitenste lus wordt gegeven.
'outer: for i in 0..4 {
for j in i..i+2 {
println!("{} {}", i, j);
if i > 1 {
continue 'outer;
}
}
println!("--");
}
uitgang 0 0
0 1
--
1 1
1 2
--
2 2
3 3
Voor i > 1
, werd de binnenlus eenmaal herhaald en --
niet afgedrukt.
Opmerking: verwar een luslabel niet met een levenslange variabele. Levenslange variabelen komen alleen voor naast een &
of als generieke parameter binnen <>
.