Strings in Rust
Beim Umgang mit Text fühlt sich Rust zum ersten Mal deutlich anders an als andere Sprachen. Das liegt vor allem daran, dass es zwei String-Typen gibt. Sobald du weißt, warum, ist das gar nicht mehr verwirrend.
&str oder String?
Abschnitt betitelt „&str oder String?“&str(„String-Slice“) – Text, der schon irgendwo existiert, meistens direkt in deinen Code geschrieben. Feste Größe, kann nicht wachsen.String– ein wachsender Text, der dir gehört. Du kannst etwas anhängen, und er liegt auf dem Heap.
fn main() { let literal: &str = "hallo"; // ein String-Slice let owned: String = String::from("hallo"); // ein eigener String
println!("{literal} / {owned}");}Eine einfache Faustregel: Wenn du nur festen Text ausgibst, reicht "so etwas" (ein &str). Wenn du Text zur Laufzeit zusammenbauen, erweitern oder ändern musst, greif zu String.
Einen String erweitern
Abschnitt betitelt „Einen String erweitern“fn main() { let mut greeting = String::from("Hallo"); greeting.push_str(", Welt"); // ein &str anhängen greeting.push('!'); // ein einzelnes char anhängen
println!("{greeting}");}Ausgabe:
Hallo, Welt!Strings verbinden
Abschnitt betitelt „Strings verbinden“Du kannst Strings mit + verbinden oder format! verwenden (das ist meistens die übersichtlichere Variante):
fn main() { let first = String::from("Hallo, "); let second = String::from("Welt!");
let combined = first + &second; // beachte das & vor second println!("{combined}");
// format! ist oft leichter zu lesen: let name = "Ferris"; let greeting = format!("Hallo, {name}!"); println!("{greeting}");}Nützliche String-Methoden
Abschnitt betitelt „Nützliche String-Methoden“Ein paar Methoden, die du ständig brauchen wirst. In diesem Beispiel bleibt der Text absichtlich auf Englisch: .len() zählt Bytes, und Umlaute wie ä, ö oder ü belegen jeweils zwei Bytes – das Ergebnis würde sich also ändern.
fn main() { let text = " Hello, Rust! ";
println!("{}", text.trim()); // "Hello, Rust!" (ohne Leerzeichen außen) println!("{}", text.to_uppercase()); // " HELLO, RUST! " println!("{}", text.to_lowercase()); // " hello, rust! " println!("{}", text.contains("Rust")); // true println!("{}", text.trim().len()); // 12 (Länge in Bytes) println!("{}", text.trim().replace("Rust", "World")); // "Hello, World!"}Über einen String iterieren
Abschnitt betitelt „Über einen String iterieren“Um Zeichen für Zeichen durchzugehen, verwendest du .chars():
fn main() { for c in "abc".chars() { println!("{c}"); }}Übungen
Abschnitt betitelt „Übungen“1. Chaotische Eingabe aufräumen
Abschnitt betitelt „1. Chaotische Eingabe aufräumen“Jemand hat " rUsT is FUN " in ein Formular getippt. Mach daraus rust is great: Entferne die überflüssigen Leerzeichen, schreib alles klein und ersetze fun durch great. Gib dann das Ergebnis und seine Länge aus. Tipp: String-Methoden lassen sich verketten, eine nach der anderen: text.trim().to_lowercase()....
Die Texte bleiben hier auf Englisch, weil das Programm die Länge in Bytes ausgibt – Umlaute würden sie verändern.
Lösung anzeigen
fn main() { let input = " rUsT is FUN ";
// erst trimmen, dann kleinschreiben, dann "fun" (jetzt klein) ersetzen let clean = input.trim().to_lowercase().replace("fun", "great");
println!("{clean}"); println!("{} bytes", clean.len());}Ausgabe:
rust is great13 bytesDie Reihenfolge ist wichtig: Würdest du .replace("fun", "great") vor .to_lowercase() aufrufen, würde nichts ersetzt – denn im Text steht dann noch FUN.
2. Eine E-Mail-Adresse bauen
Abschnitt betitelt „2. Eine E-Mail-Adresse bauen“Gegeben sind first = "Ada" und last = "Lovelace". Bau daraus den String [email protected] und gib ihn aus. Gib danach aus, ob er ein @ enthält. Tipp: format! nimmt auch Ausdrücke wie first.to_lowercase() als Argumente für seine {}-Platzhalter.
Lösung anzeigen
fn main() { let first = "Ada"; let last = "Lovelace";
let email = format!("{}.{}@example.com", first.to_lowercase(), last.to_lowercase());
println!("{email}"); println!("sieht gültig aus: {}", email.contains('@'));}Ausgabe:
sieht gültig aus: trueZusammenfassung
Abschnitt betitelt „Zusammenfassung“&strist geliehener, fester Text;Stringgehört dir und kann wachsen.- Einen
Stringerweiterst du mit.push_str()(für Text) oder.push()(für ein einzelnes Zeichen). - Nimm beim Verbinden lieber
format!als+– es ist übersichtlicher und verschiebt nichts. - Häufige Methoden:
.trim(),.to_uppercase(),.contains(),.replace(),.chars().
Kurzer Check
Abschnitt betitelt „Kurzer Check“Kurzer Check
1. Welcher String-Typ gehört dir und kann zur Laufzeit wachsen?
2. Warum bevorzugt diese Seite format! statt +, wenn mehr als ein, zwei Strings verbunden werden?
3. Warum kannst du einen Rust-String nicht mit text[0] indizieren?
4. Welche Methode hängt ein einzelnes Zeichen an einen String an, wie in greeting.push('!')?
Punkte: 0 / 4
Weiterlesen
Abschnitt betitelt „Weiterlesen“- UTF-8-kodierten Text in Strings ablegen – Die Programmiersprache Rust: das offizielle Kapitel zu
String– auch dazu, warum du nicht über eine Position indizieren kannst. - String-Slices – Die Programmiersprache Rust: was ein
&strwirklich ist, sobald du Borrowing kennst. - Strings – Rust by Example (auf Englisch): lauffähige Beispiele zu
Stringund&str, dazu Escape-Zeichen und Raw Strings. String– Doku der Standardbibliothek (auf Englisch): alle Methoden eines eigenenString, jeweils mit einem kleinen Beispiel.str– Doku der Standardbibliothek (auf Englisch): Methoden wietrim,contains,replaceundsplit, die mit jedem Text funktionieren.