if, else & Schleifen
Kontrollstrukturen in Rust: if-Ausdruecke, loop, while und for. Plus die Besonderheit: if ist in Rust ein Ausdruck mit Rueckgabewert.
Inhaltsverzeichnis
Kontrollstrukturen in Rust
Wie jede Sprache hat auch Rust if und Schleifen - aber mit ein paar rustigen Eigenheiten.
if / else
let alter = 18;
if alter >= 18 {
println!("Volljaehrig");
} else if alter >= 16 {
println!("Fast volljaehrig");
} else {
println!("Zu jung");
}
Wichtige Unterschiede zu anderen Sprachen:
- Keine Klammern um die Bedingung
- Bedingung muss ein
boolsein - nicht 0/1 oder Strings - Die Bloecke
{ ... }sind Pflicht, auch bei einer Zeile
if als Ausdruck
Das ist eine Rust-Besonderheit: if liefert einen Wert zurueck. Damit ersetzt es den ternaeren Operator ?: aus anderen Sprachen:
let punkte = 85;
let note = if punkte >= 90 {
"A"
} else if punkte >= 80 {
"B"
} else {
"C"
};
println!("Note: {}", note); // "B"
Beide Zweige muessen den gleichen Typ liefern - sonst gibt der Compiler einen Fehler.
loop - die Endlosschleife
loop laeuft, bis du sie explizit mit break abbrichst:
let mut zaehler = 0;
loop {
zaehler += 1;
if zaehler == 10 {
break;
}
}
println!("Fertig bei {}", zaehler); // 10
loop ist ebenfalls ein Ausdruck - break kann einen Wert zurueckgeben:
let mut zaehler = 0;
let ergebnis = loop {
zaehler += 1;
if zaehler == 10 {
break zaehler * 2; // gibt 20 zurueck
}
};
println!("ergebnis = {}", ergebnis); // 20
while
Laeuft, solange die Bedingung true ist:
let mut n = 10;
while n > 0 {
println!("{}...", n);
n -= 1;
}
println!("Start!");
for - der Favorit
In Rust ist for fuer Iteratoren gedacht - nicht fuer C-Style Zaehlschleifen:
Ueber eine Range iterieren
for i in 1..5 {
println!("i = {}", i); // 1, 2, 3, 4
}
for i in 1..=5 {
println!("i = {}", i); // 1, 2, 3, 4, 5 (inklusiv)
}
Ueber eine Sammlung iterieren
let namen = ["Max", "Anna", "Leo"];
for name in namen.iter() {
println!("Hallo, {}!", name);
}
// Kurzform - .iter() wird implizit aufgerufen
for name in &namen {
println!("Hallo, {}!", name);
}
Mit Index
for (i, name) in namen.iter().enumerate() {
println!("{}: {}", i, name);
}
Rueckwaerts
for i in (1..=5).rev() {
println!("{}", i); // 5, 4, 3, 2, 1
}
break und continue
Wie in anderen Sprachen:
breakverlaesst die Schleifecontinuespringt zur naechsten Iteration
for i in 1..=10 {
if i % 2 == 0 {
continue; // gerade Zahlen ueberspringen
}
if i > 7 {
break; // bei > 7 abbrechen
}
println!("{}", i); // 1, 3, 5, 7
}
Schleifen-Labels
Bei verschachtelten Schleifen kannst du gezielt eine bestimmte breaken:
'aussen: for x in 0..5 {
for y in 0..5 {
if x + y == 4 {
break 'aussen;
}
println!("{}, {}", x, y);
}
}
Kurze match-Vorschau
Rust hat ein extrem maechtiges match, das switch aus anderen Sprachen ersetzt. Wir schauen uns das im Detail bei Enums an, aber hier ein Vorgeschmack:
let zahl = 3;
let text = match zahl {
1 => "Eins",
2 => "Zwei",
3 => "Drei",
_ => "Andere Zahl", // _ = default
};
println!("{}", text); // "Drei"
match ist exhaustiv: Der Compiler erzwingt, dass du alle moeglichen Faelle abdeckst. Das verhindert vergessene Cases.
Uebersicht
if/elseohne Klammern, mit Bloecken, als Ausdruck nutzbarloopfuer Endlosschleifen - mit optionalem Rueckgabewert viabreakwhilewie gewohntforiteriert ueber Ranges (0..10) und Sammlungenbreakundcontinueggf. mit Labelsmatchals Super-Switch (kommt spaeter ausfuehrlich)
Im naechsten Kapitel: Funktionen.