Rust
Schleifen
Suche…
Syntax
Schleife { Block } // Endlosschleife
während Bedingung { Block }
Während Muster = Ausdruck { Block } ist
for pattern in expr { block } // expr muss IntoIterator implementieren
weiter // zum Ende des Schleifenkörpers springen, ggf. eine neue Iteration starten
brechen // stoppe die Schleife
' label : loop { block }
' label : while- Bedingung { Block }
' label : while let Muster = Ausdruck { Block }
' label : für Muster in Ausdruck { Block }
fortsetzen ' label // springt zum Ende des mit dem Label des Labels markierten Labels und startet ggf. eine neue Iteration
break ' label // Stoppen Sie das Label der Schleife
Grundlagen
Es gibt 4 Schleifenkonstrukte in Rust. Alle unten aufgeführten Beispiele liefern die gleiche Ausgabe.
Unendliche Schleifen
let mut x = 0;
loop {
if x > 3 { break; }
println!("{}", x);
x += 1;
}
Während Schleifen
let mut x = 0;
while x <= 3 {
println!("{}", x);
x += 1;
}
Siehe auch: Was ist der Unterschied zwischen loop
und while true
?
Musterangepasste While-Schleifen
Diese werden manchmal als while let
Loops bezeichnet.
let mut x = Some(0);
while let Some(v) = x {
println!("{}", v);
x = if v < 3 { Some(v + 1) }
else { None };
}
Dies entspricht einer match
innerhalb eines loop
:
let mut x = Some(0);
loop {
match x {
Some(v) => {
println!("{}", v);
x = if v < 3 { Some(v + 1) }
else { None };
}
_ => break,
}
}
Für Loops
In Rust kann for
Schleife nur mit einem "iterable" -Objekt verwendet werden (dh IntoIterator
sollte implementiert IntoIterator
).
for x in 0..4 {
println!("{}", x);
}
Dies ist gleichbedeutend mit dem folgenden Snippet, das while let
einschließt:
let mut iter = (0..4).into_iter();
while let Some(v) = iter.next() {
println!("{}", v);
}
Hinweis: 0..4
gibt ein Range
Objekt zurück, das bereits die Iterator
Eigenschaft implementiert. Daher ist into_iter()
notwendig, wird aber nur zur Veranschaulichung der into_iter()
for
beibehalten. Siehe einen eingehender Blick, die offiziellen Dokumente auf for
Loops und IntoIterator
.
Siehe auch: Iteratoren
Mehr über For Loops
Wie in den Grundlagen erwähnt, können wir alles verwenden, was IntoIterator
mit der for
Schleife implementiert:
let vector = vec!["foo", "bar", "baz"]; // vectors implement IntoIterator
for val in vector {
println!("{}", val);
}
Erwartete Ausgabe:
foo
bar
baz
Beachten Sie, dass das Durchlaufen des vector
auf diese Weise diesen verbraucht (nach der for
Schleife kann der vector
nicht mehr verwendet werden). Dies liegt daran, dass IntoIterator::into_iter
sich self
bewegt .
IntoIterator
wird auch von &Vec<T>
und &mut Vec<T>
implementiert (ergibt Werte mit den Typen &T
bzw. &mut T
). Sie können also die Verschiebung des vector
indem Sie ihn einfach als Referenz übergeben:
let vector = vec!["foo", "bar", "baz"];
for val in &vector {
println!("{}", val);
}
println!("{:?}", vector);
Beachten Sie, dass val
vom Typ &&str
, da vector
vom Typ Vec<&str>
.
Schleifensteuerung
Alle Schleifenkonstrukte erlauben die Verwendung von break
und continue
Anweisungen. Sie betreffen die unmittelbar umlaufende (innerste) Schleife.
Grundschleifensteuerung
break
beendet die Schleife:
for x in 0..5 {
if x > 2 { break; }
println!("{}", x);
}
Ausgabe 0
1
2
continue
beendet die aktuelle Iteration früh
for x in 0..5 {
if x < 2 { continue; }
println!("{}", x);
}
Ausgabe 2
3
4
Erweiterte Schleifensteuerung
Nehmen wir an, wir haben verschachtelte Schleifen und möchten in die äußere Schleife break
. Dann können wir Schleifenbezeichnungen verwenden, um anzugeben, für welche Schleife eine break
oder continue
gilt. Im folgenden Beispiel ist 'outer
das Etikett, das der äußeren Schleife zugewiesen wurde.
'outer: for i in 0..4 {
for j in i..i+2 {
println!("{} {}", i, j);
if i > 1 {
continue 'outer;
}
}
println!("--");
}
Ausgabe 0 0
0 1
--
1 1
1 2
--
2 2
3 3
Bei i > 1
wurde die innere Schleife nur einmal wiederholt und --
wurde nicht gedruckt.
Hinweis: Verwechseln Sie eine Schleifenbezeichnung nicht mit einer Lebensdauervariablen. Lebensdauervariablen treten nur neben einem &
oder als generischer Parameter innerhalb von <>
.