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.
Zahlentypen mit as umwandeln
Abschnitt betitelt „Zahlentypen mit as umwandeln“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}");}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}In kleinere Typen umwandeln kann Daten kosten
Abschnitt betitelt „In kleinere Typen umwandeln kann Daten kosten“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}Kommazahlen, Zeichen und Booleans umwandeln
Abschnitt betitelt „Kommazahlen, Zeichen und Booleans umwandeln“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-34255065a1Das 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.0wird in einemu8zu255). Das ist anders als bei Ganzzahlen, die überlaufen (300wurde oben zu44). - Zeichen haben eine Zahl hinter sich (ihren Unicode-Codepunkt).
'A' as u32ergibt65. Nur einu8lässt sich direkt zurück in eincharumwandeln. Für größere Zahlen nimmst duchar::from_u32, weil nicht jede Zahl ein gültiges Zeichen ist. - Booleans werden zu
1oder0. Die andere Richtung klappt nicht:1 as boollässt sich nicht kompilieren. Nimm stattdessen einen Vergleich wien != 0.
Strings in Zahlen umwandeln
Abschnitt betitelt „Strings in Zahlen umwandeln“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.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.
Zahlen in Strings umwandeln
Abschnitt betitelt „Zahlen in Strings umwandeln“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 + "!");}Übungen
Abschnitt betitelt „Übungen“1. Durchschnittsnote
Abschnitt betitelt „1. Durchschnittsnote“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: 25Durchschnitt: 8.332. Preis aus Text
Abschnitt betitelt „2. Preis aus Text“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.5Ohne as f64 würde Rust sich weigern, ein f64 mit einem i32 zu multiplizieren – denn es mischt Zahlentypen nie von selbst.
Zusammenfassung
Abschnitt betitelt „Zusammenfassung“- Rust wandelt Typen nie automatisch um – du schreibst die Umwandlung immer ausdrücklich hin.
- Mit
aswandelst 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). Auchcharundboollassen sich in Zahlen umwandeln. - Mit
.parse()wird aus Text eine Zahl, mit.to_string()geht es in die andere Richtung.
Kurzer Check
Abschnitt betitelt „Kurzer Check“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
Weiterlesen
Abschnitt betitelt „Weiterlesen“- Casting – Rust by Example (auf Englisch): viele lauffähige
as-Umwandlungen, mit Kommentaren, was genau jede davon ergibt. - Type cast expressions – The Rust Reference (auf Englisch): die vollständige Tabelle, welche Umwandlungen erlaubt sind, und die genaue Regel für jede.
- To and from Strings – Rust by Example (auf Englisch):
.to_string()und.parse()etwas ausführlicher. TryFrom– Doku der Standardbibliothek (auf Englisch): die geprüfte Umwandlung (u8::try_from(...)) für Fälle, in denen ein Wert vielleicht nicht passt.- Numeric Types – The Rust Reference (auf Englisch): Größe und Wertebereich jedes Ganzzahl- und Gleitkommatyps.