Rust: Wie man String mit String-Literalen vergleicht (match)

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

Warum Rust nicht einfach erlaubt, String mit "hallo" zu vergleichen?

\n\n

Wenn Sie gerade erst anfangen, Rust zu lernen, und bereits auf die Notwendigkeit gestoßen sind, eine Variable vom Typ String mit einem String-Literal wie "hello" oder "world" abzugleichen, haben Sie sicherlich eine seltsame Compiler-Fehler gesehen. Sie schreiben so etwas wie:

\n\n
let user_input = String::from("start");\nmatch user_input {\n    "start" => println!("Los geht's!"),\n    "stop"  => println!("Anhalten!"),\n    _       => println!("Unbekannter Befehl"),\n}\n
\n\n

Und der Compiler gibt etwas aus wie: "expected struct `String`, found `&str`". Kommt Ihnen das bekannt vor?

\n\n

Auf Stack Overflow hat die Frage "How to match a String against string literals?" Tausende von Aufrufen – das ist der wahre Schmerz von Anfängern. In diesem Artikel werden wir erklären, warum das passiert, und drei einfache Wege zeigen, das Problem zu lösen. Sie werden lernen, wie das Ownership- und Borrowing-System in Rust in der Praxis funktioniert, und werden keine Angst mehr vor Compiler-Fehlern haben.

\n\n

Die Natur des Konflikts: String vs &str

\n\n

Um das Problem zu verstehen, müssen wir uns die Grundlagen ins Gedächtnis rufen. In Rust gibt es zwei Haupttypen für die Arbeit mit Text:

\n\n
    \n
  • String – dies ist ein besitzender String, der auf dem Heap gespeichert wird. Er kann verändert, vergrößert und verkleinert werden. Beispiel: let s = String::from("hello");
  • \n
  • &str – dies ist ein String-Slice. Es ist ein Verweis auf einen Teil eines Strings (oder auf ein String-Literal, das direkt in der Programm-Binärdatei gespeichert ist). Beispiel: "hello" ist genau &'static str.
  • \n
\n\n

Wenn Sie match user_input { "start" => ... } schreiben, versuchen Sie, einen String mit einem &str zu vergleichen. Der Compiler sagt: "Ich weiß nicht, wie ich sie direkt abgleichen soll, die Typen sind unterschiedlich!". Und das ist gut – Rust schützt Sie vor impliziten Konvertierungen, die zu Leistungseinbußen oder versteckten Fehlern führen könnten.

\n\n

Was also tun? Es gibt drei einfache und elegante Lösungen.

\n\n

Lösung 1: Ausleihen mit as_str()

\n\n

Der direkteste und verständlichste Weg ist, aus einem String einen String-Slice (&str) mit der Methode as_str() zu gewinnen. Diese Methode gibt einen Verweis auf den Inhalt des Strings zurück, ohne ihn zu kopieren. Das sieht so aus:

\n\n
fn main() {\n    let command = String::from("start");\n\n    match command.as_str() {\n        "start" => println!("Systemstart..."),\n        "stop"  => println!("Stopp..."),\n        "pause" => println!("Pause..."),\n        _       => println!("Unbekannter Befehl: {}", command),\n    }\n}\n
\n\n

Warum funktioniert das? as_str() gibt ein &str zurück, das nun mit Literalen verglichen werden kann. Rust sieht, dass beide Operanden &str sind, und der Pattern-Matching funktioniert perfekt.

\n\n

Vorteile: Einfachheit, Lesbarkeit, keine zusätzlichen Kosten (Ausleihen, nicht Kopieren).

\n\n

Nachteile: Man muss sich an den Methodenaufruf erinnern. Aber das ist eine Kleinigkeit.

\n\n

Lösung 2: Vergleich in einer if-Bedingung

\n\n

Wenn Sie nicht die volle Leistungsfähigkeit von match benötigen, können Sie einfache if-Bedingungen mit der Methode eq() oder dem Operator == verwenden. Rust kann String und &str über das Trait PartialEq vergleichen, das für dieses Typenpaar implementiert ist.

\n\n
fn main() {\n    let user_input = String::from("admin");\n\n    if user_input == "admin" {\n        println!("Zugriff gewährt!");\n    } else if user_input == "guest" {\n        println!("Gastzugang");\n    } else {\n        println!("Ungültiger Login");\n    }\n}\n
\n\n

Das funktioniert, weil der Compiler beim Vergleich automatisch String in &str umwandelt. Aber in match gibt es diese Umwandlung nicht – dort wird eine exakte Übereinstimmung verlangt.

Blogs

Buchempfehlungen