Geschichte der Frage
Der match-Operator in Rust ist ein leistungsstarkes Werkzeug für Musterübereinstimmungen, das aus funktionalen Sprachen entlehnt wurde. Im Gegensatz zu Analogien in C/C++ wird in Rust eine strenge Vollständigkeitsprüfung (Exhaustiveness Checking) durchgeführt, und für jede mögliche Variante müssen entsprechende Verzweigungen vorhanden sein.
Problem
Fehler bei der Arbeit mit match hängen häufig mit der falschen Berücksichtigung aller Varianten eines Typs (z.B. enum), der falschen Handhabung von Guards (Bedingungen für Verzweigungen) oder einer komplexen verschachtelten Struktur zusammen. Falsche Bearbeitung führt zu Kompilierungsfehlern oder zu implizit falscher Logik.
Lösung
_).if nach dem Muster).Beispielcode:
enum Shape { Circle(f64), Rectangle { width: f64, height: f64 }, } fn print_area(s: Shape) { match s { Shape::Circle(r) if r > 0.0 => println!("Fläche = {}", 3.14 * r * r), Shape::Rectangle { width, height } if width > 0.0 && height > 0.0 => println!("Fläche = {}", width * height), _ => println!("ungültige Form"), } }
Wesentliche Merkmale:
Beeinflusst die Reihenfolge der Verzweigungen in match die Ausführung?
Ja, die Reihenfolge der Verzweigungen ist wichtig: Sobald eine Übereinstimmung gefunden wird, werden die folgenden nicht mehr überprüft. Dies ist besonders kritisch bei Pattern Guards — wenn eine Verzweigung mit Guard vorher steht, wird sie den Wert vor dem Catch-All abfangen.
Ist ein Catch-All (_) bei match über enum zwingend erforderlich?
Nein, wenn Sie alle Fälle explizit behandelt haben (und die Typdefinitionen sich nicht im Laufe der Zeit ändern). Ein Catch-All ist jedoch erforderlich, wenn mit Typen gearbeitet wird, die zusätzliche Werte erhalten könnten, oder wenn man nicht alle Verzweigungen explizit handhaben möchte.
Kann man in einer match-Verzweigung mehrere Muster (Alternativen) verwenden?
Ja. Durch senkrechte Striche (|) können Muster kombiniert werden:
match x { 1 | 2 | 3 => println!("eins, zwei oder drei"), _ => println!("etwas anderes"), }
_ zu früh verwenden (vor spezifischen Verzweigungen)Ein Entwickler schrieb ein match mit Catch-All am Anfang und konnte spezifische Fälle nicht korrekt behandeln.
Vorteile:
Das Programm kompiliert.
Nachteile:
Spezifische Logik funktioniert nie, ein Teil des Codes wird nicht abgedeckt.
Explizite Behandlung aller Varianten des enums, Catch-All nur als letzte Verzweigung, separate Guards für atypische Fälle.
Vorteile:
Vorhersehbarkeit, der Compiler hilft, eine Variante nicht zu vergessen, einfach Typen zu erweitern.
Nachteile:
Zusätzlicher Vorlagen-Code bei einer großen Anzahl von Varianten.