====== Lyx – Pattern Matching (match) ====== Das ''match''-Statement ist eines der mächtigsten Kontrollfluss-Elemente in Lyx. Es erlaubt den Vergleich eines Wertes gegen eine Reihe von Mustern (Patterns). Im Gegensatz zu ''switch'' in C oder Java ist ''match'' in Lyx **typsicher** und **exhaustiv** (vollständig). ===== 1. Grundlegende Syntax ===== Ein ''match''-Block prüft einen Ausdruck und führt den ersten passenden Arm aus. match (error_code) { case 0 => { PrintStr("OK"); } case 404 => { PrintStr("Not Found"); } case 500 => { PrintStr("Server Error"); } default => { PrintStr("Unknown Error"); } } * **=> (Fat Arrow)**: Trennt das Muster vom auszuführenden Code-Block. * **default**: Der Auffang-Arm (Catch-all), falls kein anderes Muster passt. ===== 2. Matching auf Enums ===== Besonders stark ist ''match'' in Verbindung mit Aufzählungstypen (Enums). Der Compiler prüft hierbei die **Exhaustivität**. enum FlightState { Idle, Taxiing, InAir, Landing } fn handle_state(s: FlightState) { match (s) { case FlightState.Idle => { stop_engines(); } case FlightState.Taxiing => { check_flaps(); } case FlightState.InAir => { retract_gear(); } case FlightState.Landing => { deploy_gear(); } // Kein 'default' nötig, da alle Enum-Werte abgedeckt sind! } } > **Compiler-Garantie:** Wenn du einen neuen Wert zum Enum ''FlightState'' hinzufügst, ohne das ''match'' zu aktualisieren, wirft der Compiler einen Fehler (**Inexhaustive Match**). Dies ist eine wichtige Sicherheitsfunktion für [[lyx_-_programmiersprache:do-178c|DO-178C]]. ===== 3. Range-Matching ===== In Lyx können auch Wertebereiche direkt in den Cases geprüft werden. Dies ist besonders nützlich für die Auswertung von Sensordaten. match (altitude) { case 0..500 => { set_mode(Landing); } case 501..30000 => { set_mode(Cruise); } case 30001.. => { set_mode(HighAltitude); } default => { panic("Invalid altitude"); } } ===== 4. Typ-Deconstruction (v0.7.x+) ===== Lyx erlaubt das "Hineinschauen" in komplexe Strukturen (Deconstruction), um direkt auf deren Felder zu matchen. type Event = struct { id: int, active: bool } fn process(e: Event) { match (e) { case Event { id: 1, active: true } => { start_system(); } case Event { active: false } => { log_inactive(); } default => { ignore(); } } } ===== 5. Vergleich: match vs. if-else ===== ^ Feature ^ match ^ if-else ^ | **Lesbarkeit** | Hoch bei vielen Fällen | Hoch bei einfachen Bedingungen | | **Vollständigkeit** | Vom Compiler erzwungen | Manuell (Fehleranfällig) | | **Performance** | Optimiert via Jump-Table | Lineare Prüfung (langsam) | | **Komplexität** | Unterstützt Deconstruction | Nur boolesche Logik | ===== 6. Best Practices ===== * **Vermeide riesige default-Blöcke**: Versuche lieber, alle Fälle explizit zu benennen, um vom Compiler gewarnt zu werden, wenn sich die Logik ändert. * **Nutze Blöcke**: Auch wenn ein Case nur eine Zeile hat, erhöhen geschweifte Klammern ''{ }'' die Wartbarkeit im Aerospace-Umfeld. * **Range-Checks**: Nutze Ranges (''0..100'') statt komplexer Vergleiche (''x >= 0 && x <= 100''), da der Compiler diese besser optimieren kann.