Einleitung: Warum erlaubt Rust nicht einfach, einen String in eine Zahl zu konvertieren?
Wenn Sie von Python oder JavaScript kommen, sind Sie Magie wie int("42") oder parseInt("42") gewohnt. In Rust funktioniert dieser Trick nicht – der Compiler verlangt, dass Sie genau angeben, in welchen Typ Sie den String umwandeln möchten. Warum? Weil Rust eine Sprache ist, die keine Nachlässigkeit verzeiht. Sie zwingt Sie, über Randfälle nachzudenken: Was, wenn der String keine Zahl enthält? Was, wenn die Zahl für den gewählten Typ zu groß ist?
In diesem Artikel behandeln wir die häufigste Frage auf Stack Overflow unter Rust-Anfängern: Wie konvertiert man String in int. Sie erhalten nicht nur fertigen Code, sondern auch ein vollständiges Verständnis dessen, was unter der Haube passiert.
Die Methode parse() – das wichtigste Werkzeug zur Konvertierung
Der Hauptweg, einen String in eine Zahl in Rust umzuwandeln, ist die Methode parse(), die für die Typen String und &str verfügbar ist. Sie wird über das Trait FromStr implementiert und gibt Result<T, E> zurück.
Basisbeispiel: String → i32
fn main() { let number_string = String::from("42"); let number: i32 = number_string.parse().unwrap(); println!("Zahl: {}", number); // Ausgabe: Zahl: 42}Beachten Sie unwrap(). Dies ist eine schnelle Möglichkeit, den Wert aus Result zu extrahieren, aber sie ist gefährlich: Wenn der String keine Zahl ist, gerät das Programm in Panik und stürzt ab.
Korrekte Fehlerbehandlung
In echtem Code sollten Sie unwrap() niemals gedankenlos verwenden. So machen Sie es richtig:
use std::num::ParseIntError;
fn main() { let input = String::from("hallo"); match input.parse::<i32>() { Ok(number) => println!("Erfolgreich: {}", number), Err(e) => println!("Konvertierungsfehler: {}", e), }}Oder eine prägnantere Variante mit if let:
fn main() { let input = String::from("2024"); if let Ok(year) = input.parse::<i32>() { println!("Jahr: {}", year); } else { println!("String konnte nicht geparst werden"); }}Verfügbare Ganzzahltypen für die Konvertierung
Rust bietet eine reiche Auswahl an Ganzzahltypen. Sie können einen String in jeden von ihnen konvertieren:
i8,i16,i32,i64,i128– vorzeichenbehaftete Ganzzahlenu8,u16,u32,u64,u128– vorzeichenlose Ganzzahlenisize,usize– Größe abhängig von der Architektur
Beispiel für die Konvertierung in verschiedene Typen:
fn main() { let val = "255"; let a: u8 = val.parse().unwrap(); // 255 let b: i16 = val.parse().unwrap(); // 255 let c: u32 = val.parse().unwrap(); // 255 // Aber das hier würde einen Fehler verursachen – 255 passt nicht in i8 // let d: i8 = val.parse().unwrap(); // PANIK!}Fortgeschrittene Techniken: from_str und benutzerdefinierte Typen
Die Methode parse() ruft intern from_str() aus dem Trait FromStr auf. Sie können dieses Trait für Ihre eigenen Strukturen implementieren:
use std::str::FromStr;use std::num::ParseIntError;
#[derive(Debug)]struct Version { major: u32, minor: u32,}
impl FromStr for Version { type Err = ParseIntError; fn from_str(s: &str) -> Result<Self, Self::Err> { let parts: Vec<&str> = s.split('.').collect(); if parts.len() != 2 { // Erstellen eigenen Fehler, aber für das Beispiel verwenden wir ParseIntError return Err("1.0".parse::<u32>().unwrap_err()); } let major = parts[0].p