Konvertierung von Integer in String in Rust: Magie ohne unwrap und Makros

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Einleitung: Warum kann man in Rust nicht einfach eine Zahl mit einem String addieren?

\n\n

Wenn Sie von Python oder JavaScript kommen, sind Sie es gewohnt, etwas wie str(42) oder 42 + "" zu schreiben. In Rust funktioniert dieser Trick nicht. Der Compiler fragt streng: "Welchen Typ möchtest du haben? Integer? String? Entscheide dich!"

\n\n

Die Frage "How do I convert from an integer to a string?" ist eine der beliebtesten auf Stack Overflow im Bereich Rust. Tausende Entwickler zerbrechen sich den Kopf, warum ihr Code nicht kompiliert, wenn sie versuchen, Folgendes zu schreiben:

\n\n
let number = 42;\nlet text = number; // Fehler: expected `&str`, found `i32`
\n\n

Heute werfen wir einen Blick unter die Haube dieser Konvertierung. Sie erfahren nicht nur wie man es macht, sondern auch wie es funktioniert – auf der Ebene von Traits, Allokationen und sogar Assembler. Los geht's!

\n\n

Der einfachste Weg: Die Methode to_string()

\n\n

In Rust haben, wie in den meisten modernen Sprachen, die ganzzahligen Typen eine Methode to_string(). Sie sieht täuschend einfach aus:

\n\n
fn main() {\n    let num: i32 = 255;\n    let s: String = num.to_string();\n    println!("{}", s); // Gibt aus: "255"\n}
\n\n

Dies funktioniert für alle ganzzahligen Typen: i8, u32, i64, usize usw.

\n\n

Was passiert unter der Haube?

\n\n

Die Methode to_string() ist keine Compiler-Magie. Sie ist über den Trait Display implementiert. In der Standardbibliothek von Rust gibt es diese Implementierung:

\n\n
// Vereinfachte Version aus der Standardbibliothek\nimpl<T: fmt::Display> ToString for T {\n    #[inline]\n    fn to_string(&self) -> String {\n        use fmt::Write;\n        let mut buf = String::new();\n        // Hier wird die Methode fmt() des Traits Display aufgerufen\n        let _ = buf.write_fmt(format_args!("{}", self));\n        buf.shrink_to_fit(); // Speicheroptimierung\n        buf\n    }\n}
\n\n

Der entscheidende Punkt: to_string() erzeugt einen neuen String auf dem Heap. Jeder Aufruf ist eine Speicherallokation. Bei Hunderttausenden von Konvertierungen kann dies zu einem Leistungsengpass werden.

\n\n

Alternative: Das Makro format!

\n\n

Die zweite beliebte Methode ist das Makro format!. Es funktioniert wie println!, gibt aber anstatt in die Konsole einen String zurück:

\n\n
fn main() {\n    let num = 1024;\n    let s = format!("{}", num);\n    println!("Länge des Strings: {}", s.len()); // 4\n}
\n\n

Der Unterschied zwischen to_string() und format! ist minimal. to_string() ruft intern format_args! und write_fmt auf. Im Grunde ist es dasselbe. Die Wahl ist eine Frage des Stils und der Lesbarkeit.

\n\n

Wann sollte man format! verwenden?

\n
    \n
  • Wenn eine Zahl in die Mitte eines Strings eingefügt werden soll: format!("Zahl: {}", num)
  • \n
  • Wenn das Format komplex ist (hexadezimal, mit Trennzeichen): format!("{:#x}", 255) → "0xff"
  • \n
  • Wenn die Ausdruckskraft des Codes wichtig ist
  • \n
\n\n

Trait Display vs ToString: Was ist schneller?

\n\n

Wenn Sie eine Bibliothek oder leistungskritischen Code schreiben, verwenden Sie direkt den Trait Display über write! in einen Puffer. Dies ermöglicht die Wiederverwendung von bereits allokiertem Speicher:

\n\n
use std::fmt::Write;\n\nfn main() {\n    let num = 42;\n    let mut buffer = String::with_capacity(20); // Speicher vorab allokieren\n\n    // Zahl in den Puffer schreiben\n    write!(buffer, "{}", num).unwrap();\n    println!("{}", buffer); // "42"\n\n    // Leeren und wiederverwenden\n    buffer.clear();\n    write!(buffer, "{}", 256).unwrap();\n    println!("{}", buffer); // "256"\n}
\n\n

Dieser Ansatz bietet eine 2-3x Leistungssteigerung in Schleifen, in denen wiederholt Zahlen in Strings konvertiert werden müssen, da die Speicherallokation nur einmal erfolgt.

Blogs

Buchempfehlungen