Zum Inhalt springen

Typumwandlung in Rust

Rust wandelt einen Typ nie automatisch in einen anderen um. Wenn du ein i32 und ein f64 im selben Ausdruck mischst, lässt sich der Code nicht kompilieren. Du musst die Umwandlung ausdrücklich hinschreiben. Das ist Absicht: Stille Umwandlungen sind in anderen Sprachen eine häufige Fehlerquelle.

Mit dem Schlüsselwort as wandelst du einen Zahlentyp in einen anderen um (Casting):

fn main() {
let x: i32 = 10;
let y: f64 = x as f64; // i32 -> f64
println!("{y}");
}
▶ Selbst ausprobieren

Das ist wichtiger, als es aussieht. Teil mal zwei Ganzzahlen ohne Umwandlung: Du bekommst eine Ganzzahldivision statt des Ergebnisses mit Nachkommastellen, das du wahrscheinlich wolltest.

fn main() {
let a = 10;
let b = 3;
println!("{}", a / b); // 3 (Ganzzahldivision)
println!("{}", a as f64 / b as f64); // 3.3333333333333335
}
▶ Selbst ausprobieren

Wenn du von einem größeren Typ in einen kleineren umwandelst (etwa von i32 nach u8), schlägt das nicht fehl. Der Wert wird einfach abgeschnitten – und das Ergebnis kann dich überraschen:

fn main() {
let big: i32 = 300;
let small = big as u8; // u8 fasst nur 0-255
println!("{small}"); // 44, nicht 300 – der Wert ist übergelaufen
}
▶ Selbst ausprobieren

as funktioniert mit ein paar mehr Typen als nur ganzen Zahlen. Für jeden gibt es eine Regel, die du kennen solltest:

fn main() {
println!("{}", 3.99_f64 as i32); // 3: die Nachkommastellen werden abgeschnitten
println!("{}", -3.99_f64 as i32); // -3: Richtung null abgeschnitten, nicht abgerundet
println!("{}", 3.99_f64.round() as i32); // 4: vorher runden, wenn du das willst
println!("{}", 300.0_f64 as u8); // 255: zu groß, also bleibt es beim Maximum
println!("{}", -5.0_f64 as u8); // 0: zu klein, also bleibt es beim Minimum
println!("{}", 'A' as u32); // 65: die Code-Nummer eines char
println!("{}", 97_u8 as char); // a: und wieder zurück
println!("{}", true as i32); // 1 (false wäre 0)
}

Ausgabe:

3
-3
4
255
0
65
a
1
▶ Selbst ausprobieren

Das solltest du dir merken:

  • Kommazahl zu Ganzzahl wirft alles nach dem Dezimalpunkt weg. Es wird nicht gerundet. Ruf vorher .round() auf, wenn du die nächste ganze Zahl willst.
  • Kommazahlen außerhalb des Bereichs werden auf den nächsten passenden Wert begrenzt (300.0 wird in einem u8 zu 255). Das ist anders als bei Ganzzahlen, die überlaufen (300 wurde oben zu 44).
  • Zeichen haben eine Zahl hinter sich (ihren Unicode-Codepunkt). 'A' as u32 ergibt 65. Nur ein u8 lässt sich direkt zurück in ein char umwandeln. Für größere Zahlen nimmst du char::from_u32, weil nicht jede Zahl ein gültiges Zeichen ist.
  • Booleans werden zu 1 oder 0. Die andere Richtung klappt nicht: 1 as bool lässt sich nicht kompilieren. Nimm stattdessen einen Vergleich wie n != 0.

as funktioniert nur zwischen Zahlentypen. Um Text in eine Zahl zu verwandeln – zum Beispiel etwas, das ein Benutzer eingetippt hat – verwendest du .parse():

fn main() {
let text = "42";
let number: i32 = text.parse().expect("keine gültige Zahl");
println!("{}", number + 8);
}

Ausgabe:

50
▶ Selbst ausprobieren

.parse() kann fehlschlagen (was, wenn der Text gar keine Zahl ist?). Deshalb gibt es nicht direkt die Zahl zurück, sondern ein Result. Result haben wir noch nicht behandelt. Fürs Erste ist .expect("Nachricht") eine einfache Art zu sagen: „Wenn das schiefgeht, brich mit dieser Nachricht ab.“ Wie du das richtig behandelst, siehst du auf der Seite Result.

Die andere Richtung ist einfacher: Fast jeder Typ lässt sich mit .to_string() in einen String verwandeln:

fn main() {
let number = 42;
let text = number.to_string();
println!("{}", text + "!");
}
▶ Selbst ausprobieren

Speichere drei Testergebnisse als i32-Werte: 7, 8 und 10. Gib ihre Summe aus und dann ihren Durchschnitt mit zwei Nachkommastellen. Tipp: Wenn du zwei Ganzzahlen teilst, bekommst du 8 statt 8.33. Wandle die Summe also zuerst in ein f64 um. {:.2} gibt zwei Nachkommastellen aus.

Lösung anzeigen
fn main() {
let a: i32 = 7;
let b: i32 = 8;
let c: i32 = 10;
let sum = a + b + c;
let average = sum as f64 / 3.0; // 25.0 / 3.0, nicht 25 / 3
println!("Summe: {sum}");
println!("Durchschnitt: {:.2}", average);
}

Ausgabe:

Summe: 25
Durchschnitt: 8.33
▶ Selbst ausprobieren

Ein Shop liefert dir den Preis als Text, "4.50", und die Menge als i32, 3. Wandle den Text in ein f64 um, multipliziere ihn mit der Menge und gib Gesamt: 13.5 aus. Tipp: Du brauchst beide Werkzeuge von dieser Seite: .parse() für den Text und as f64 für die Menge.

Lösung anzeigen
fn main() {
let price_text = "4.50";
let quantity: i32 = 3;
let price: f64 = price_text.parse().expect("kein gültiger Preis");
let total = price * quantity as f64; // f64 * f64
println!("Gesamt: {total}");
}

Ausgabe:

Gesamt: 13.5
▶ Selbst ausprobieren

Ohne as f64 würde Rust sich weigern, ein f64 mit einem i32 zu multiplizieren – denn es mischt Zahlentypen nie von selbst.

  • Rust wandelt Typen nie automatisch um – du schreibst die Umwandlung immer ausdrücklich hin.
  • Mit as wandelst du zwischen Zahlentypen um: x as f64, x as u8.
  • Beim Umwandeln in einen kleineren Typ wird still abgeschnitten – es gibt keinen Fehler, also sei vorsichtig.
  • Von Kommazahl zu Ganzzahl werden die Nachkommastellen abgeschnitten (zum Runden vorher .round() aufrufen). Auch char und bool lassen sich in Zahlen umwandeln.
  • Mit .parse() wird aus Text eine Zahl, mit .to_string() geht es in die andere Richtung.

Kurzer Check

1. Was passiert, wenn du in Rust zwei Ganzzahlen wie 10 / 3 ohne Umwandlung teilst?

2. Was passiert, wenn du 300_i32 as u8 umwandelst?

3. Was gibt .parse() beim Umwandeln eines Strings in eine Zahl zurück, da die Umwandlung fehlschlagen kann?

Punkte: 0 / 3