Zum Inhalt springen

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 („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}");
}
▶ Selbst ausprobieren

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.

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!
▶ Selbst ausprobieren

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}");
}
▶ Selbst ausprobieren

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!"
}
▶ Selbst ausprobieren

Um Zeichen für Zeichen durchzugehen, verwendest du .chars():

fn main() {
for c in "abc".chars() {
println!("{c}");
}
}
▶ Selbst ausprobieren

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 great
13 bytes
▶ Selbst ausprobieren

Die Reihenfolge ist wichtig: Würdest du .replace("fun", "great") vor .to_lowercase() aufrufen, würde nichts ersetzt – denn im Text steht dann noch FUN.

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: true
▶ Selbst ausprobieren
  • &str ist geliehener, fester Text; String gehört dir und kann wachsen.
  • Einen String erweiterst 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

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