Zum Inhalt springen

For-Schleifen in Rust

for durchläuft einen Bereich oder eine Collection, ein Element nach dem anderen. Von den drei Schleifenarten in Rust ist das die, zu der du am häufigsten greifen wirst.

fn main() {
for i in 1..=5 {
println!("{i}");
}
}

Ausgabe:

1
2
3
4
5
▶ Selbst ausprobieren

1..=5 ist ein Bereich (Range), der beide Enden einschließt (1 bis 5). Lässt du das = weg – also 1..5 –, hört er eins vorher auf, und du bekommst 1 bis 4. Über diesen „Um-eins-daneben“-Fehler stolpert man leicht. Prüf also lieber zweimal, welche Variante du meinst.

Hier spielt for seine Stärke richtig aus: Du durchläufst ein Array oder einen Vektor, ohne selbst einen Index mitzuführen:

fn main() {
let fruits = ["Apfel", "Banane", "Kirsche"];
for fruit in fruits {
println!("{fruit}");
}
}

Ausgabe:

Apfel
Banane
Kirsche
▶ Selbst ausprobieren

Stell dir zum Vergleich vor, du zählst mit einer while-Schleife von Hand mit und greifst per Index (fruits[i]) zu. Die for-Variante ist kürzer, und es gibt keinen Index, den du falsch setzen kannst. Mehr über Arrays und Vektoren erfährst du auf den Seiten Arrays und Vektoren.

Brauchst du sowohl die Position als auch den Wert, nimm .enumerate():

fn main() {
let fruits = ["Apfel", "Banane", "Kirsche"];
for (index, fruit) in fruits.iter().enumerate() {
println!("{index}: {fruit}");
}
}

Ausgabe:

0: Apfel
1: Banane
2: Kirsche
▶ Selbst ausprobieren

Der Teil (index, fruit) ist ein Tupel-Muster: Jeder Durchlauf liefert dir ein Paar, und die Schleife zerlegt es für dich in zwei Variablen.

Was, wenn du von 3 herunterzählen oder nur jede zweite Zahl besuchen willst? Naheliegend wäre ein Bereich, der rückwärts läuft, etwa 3..=1. Das kompiliert zwar, aber die Schleife läuft kein einziges Mal. Ein Bereich zählt nur aufwärts. Ist der Anfang größer als das Ende, ist der Bereich einfach leer.

Nimm stattdessen einen normalen Bereich und ändere, wie du ihn durchläufst:

  • .rev() geht den Bereich rückwärts durch.
  • .step_by(n) nimmt jeden n-ten Wert, beginnend mit dem ersten.
fn main() {
for i in (1..=3).rev() {
println!("{i}...");
}
println!("Los!");
for even in (0..=10).step_by(2) {
print!("{even} ");
}
println!();
for i in 3..=1 {
println!("das wird nie ausgegeben: {i}");
}
}

Ausgabe:

3...
2...
1...
Los!
0 2 4 6 8 10
▶ Selbst ausprobieren

Achte auf die Klammern: (1..=3).rev(). Ohne sie würde Rust 1..=3.rev() als „1 bis 3.rev()“ lesen – und das willst du nicht. Du kannst beides auch kombinieren: (0..=10).rev().step_by(5) ergibt 10, 5, 0.

Du könntest eine Zählschleife auch mit while schreiben. Aber for mit einem Bereich räumt eine ganze Kategorie von Fehlern aus dem Weg: Es gibt keinen Zähler, den du zu erhöhen vergessen kannst, und du läufst nicht aus Versehen einen Schritt über das Ende eines Arrays hinaus. Rust-Entwickler nehmen standardmäßig for und greifen nur dann zu while, wenn es keinen natürlichen Bereich und keine Collection zum Durchlaufen gibt.

Gib die 7er-Reihe aus, von 7 x 1 = 7 bis 7 x 10 = 70. Tipp: Eine einzige for-Schleife über 1..=10 reicht. Die Multiplikation kannst du direkt in println! erledigen.

Lösung anzeigen
fn main() {
for i in 1..=10 {
println!("7 x {i} = {}", 7 * i);
}
}

Ausgabe:

7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
7 x 4 = 28
7 x 5 = 35
7 x 6 = 42
7 x 7 = 49
7 x 8 = 56
7 x 9 = 63
7 x 10 = 70
▶ Selbst ausprobieren

Benannte Variablen wie {i} dürfen direkt in die geschweiften Klammern. Eine Rechnung wie 7 * i darf das nicht. Deshalb steht dort ein leeres {}, und der Wert folgt nach dem Komma.

Addiere alle ungeraden Zahlen von 1 bis 99 und gib die Summe aus. Tipp: (1..100).step_by(2) liefert dir 1, 3, 5, … 99. Halte eine mut-Summe außerhalb der Schleife.

Lösung anzeigen
fn main() {
let mut total = 0;
for n in (1..100).step_by(2) {
total += n;
}
println!("Die ungeraden Zahlen von 1 bis 99 ergeben zusammen {total}");
}

Ausgabe:

Die ungeraden Zahlen von 1 bis 99 ergeben zusammen 2500
▶ Selbst ausprobieren

Alternativ kannst du 1..100 durchlaufen und n nur dann addieren, wenn n % 2 == 1 ist. Beides funktioniert. step_by überspringt die geraden Zahlen einfach, statt jede einzeln zu prüfen.

  • for element in bereich_oder_collection { ... } ist die Alltagsschleife in Rust.
  • 1..=5 schließt beide Enden ein; 1..5 hört eins vor der 5 auf.
  • Durchlauf Arrays und Vektoren direkt, um jeden Wert ohne eigenen Index zu bekommen.
  • Nimm .enumerate(), wenn du neben dem Wert auch den Index brauchst.
  • Ein Rückwärts-Bereich wie 3..=1 ist leer. Zähl mit (1..=3).rev() herunter und überspring mit .step_by(n) Werte.

Kurzer Check

1. Was ist in einer for-Schleife der Unterschied zwischen 1..=5 und 1..5?

2. Wie bekommst du beim Durchlaufen einer Collection sowohl den Index als auch den Wert?

3. Warum ist for zum Durchzählen einer Collection meist besser als while?

4. Was macht for i in 5..=1 { ... }?

Punkte: 0 / 4