Ein enum definiert einen Typ, dessen gültige Werte eine abgeschlossene, benannte Menge bilden. Der Compiler kennt alle Werte zur Compile-Zeit — das ist die Grundlage der Exhaustivitätsprüfung in match: Wird ein Enum-Wert nicht behandelt, ist es ein Fehler, keine Warnung.
Enums sind in Lyx ganzzahlige Typen (intern int64) mit benannten Konstanten. Sie haben keine Methoden und keine Vererbung — ihr einziger Zweck ist die typsichere Zustandsdarstellung.
→ Pattern Matching · Datentypen · DO-178C
// Einfachster Fall: Werte beginnen bei 0 und zählen aufwärts
enum Direction { North, South, East, West }
// North=0, South=1, East=2, West=3
// Explizite Werte — beliebige int64-Konstanten
enum HttpStatus {
Ok = 200,
Created = 201,
NotFound = 404,
ServerErr = 500
}
// Gemischt: erste Konstante setzt den Startwert, die folgenden zählen weiter
enum Priority {
Low = 1,
Medium, // = 2
High, // = 3
Critical // = 4
}
Regeln:
{ A = 1, B = 1 } ist ein Compiler-Fehler.enum Empty {} — selten sinnvoll, aber erlaubt).Ein einfaches Anwendungsbeispiel:
enum Color { Red, Green, Blue }
// Variablendeklaration
var c: Color := Color::Red;
// Übergabe als Parameter
fn PrintColor(col: Color): void {
match (col) {
case Color::Red => Print("Rot\n");
case Color::Green => Print("Grün\n");
case Color::Blue => Print("Blau\n");
}
}
// Rückgabe aus Funktion
fn OppositeDirection(d: Direction): Direction {
return match (d) {
case Direction::North => Direction::South;
case Direction::South => Direction::North;
case Direction::East => Direction::West;
case Direction::West => Direction::East;
};
}
Der Zugriff auf einen Enum-Wert erfolgt immer mit EnumName::Wert — der Namespace-Qualifier ist Pflicht. Das verhindert Namenskollisionen zwischen verschiedenen Enums.
Die Stärke von Enums zeigt sich in Kombination mit match: Der Compiler erzwingt, dass jeder mögliche Wert behandelt wird.
enum FlightPhase {
Preflight, Taxiing, Takeoff, Climbing,
Cruise, Descending, Approach, Landing, Rollout
}
fn PhaseToString(p: FlightPhase): pchar {
return match (p) {
case FlightPhase::Preflight => "Vor dem Start";
case FlightPhase::Taxiing => "Rollen";
case FlightPhase::Takeoff => "Start";
case FlightPhase::Climbing => "Steigflug";
case FlightPhase::Cruise => "Reiseflug";
case FlightPhase::Descending => "Sinkflug";
case FlightPhase::Approach => "Anflug";
case FlightPhase::Landing => "Landung";
case FlightPhase::Rollout => "Ausrollen";
};
}
Wird später FlightPhase::GoAround hinzugefügt, meldet der Compiler:
error: non-exhaustive match — FlightPhase::GoAround not covered
--> flight_ctrl.lyx:12:12
hint: add 'case FlightPhase::GoAround =>' or a 'default =>' arm
Das ist eine Sicherheitsgarantie: Neue Zustände können nicht unbehandelt durchrutschen.
default unterdrückt die Exhaustivitätsprüfung. Das ist explizit erlaubt, aber sparsam einsetzen:
fn IsErrorStatus(s: HttpStatus): bool {
return match (s) {
case HttpStatus::ServerErr => true;
default => false;
// Explizite Entscheidung: alle nicht genannten Werte sind "kein Fehler"
// Risiko: neuer Wert wie HttpStatus::GatewayTimeout wird stillschweigend false
};
}
In DO-178C DAL-A/B-Code istdefaultbei zustandsbehafteten Enums ein Compiler-Fehler wenn@dal(A)oder@dal(B)gesetzt ist. Alle Zustände müssen explizit behandelt sein.
Intern ist jeder Enum-Wert ein int64. Die explizite Konvertierung erfolgt mit as:
enum HttpStatus { Ok = 200, NotFound = 404, ServerErr = 500 }
// Enum → int64
var code: int64 := HttpStatus::Ok as int64; // 200
// int64 → Enum (unsafe: der Compiler prüft den Wert nicht)
var s: HttpStatus := 404 as HttpStatus;
// In der Praxis: Wert aus Netzwerk empfangen, in Enum konvertieren
fn ParseStatus(raw: int64): HttpStatus {
return match (raw) {
case 200 => HttpStatus::Ok;
case 404 => HttpStatus::NotFound;
case 500 => HttpStatus::ServerErr;
default => HttpStatus::ServerErr; // Fallback bei unbekanntem Code
};
}
Die KonvertierungintVal as HttpStatusist technisch möglich, aber gefährlich: Der Wert999wäre ein ungültigerHttpStatus. In@dal(A)-Code ist der direkte Cast vonint64zu einem Enum verboten — stattdessen mussParseStatusoder eine vergleichbare Funktion mit explizitemmatchverwendet werden.
Für Bit-Masken werden Enums mit Zweierpotenzen als Werte deklariert und mit Integer-Operatoren kombiniert:
enum Permission {
Read = 0x01, // Bit 0
Write = 0x02, // Bit 1
Execute = 0x04, // Bit 2
Admin = 0x08 // Bit 3
}
// Mehrere Flags kombinieren (als int64 — nicht als Permission)
var perms: int64 := Permission::Read as int64 | Permission::Write as int64;
// Flag prüfen
fn HasPermission(perms: int64, flag: Permission): bool {
return (perms & (flag as int64)) != 0;
}
fn main(): int64 {
var p: int64 := Permission::Read as int64 | Permission::Execute as int64;
if (HasPermission(p, Permission::Write)) {
PrintLn("Schreiben erlaubt");
} else {
Print("Kein Schreibzugriff\n"); // Dieser Zweig wird ausgeführt
}
return 0;
}
Bit-Flag-Enums werden immer als int64 kombiniert — Lyx bietet keinen speziellen Bitset-Typ. Das ist ein bewusstes Design: Bitoperationen sind explizit und direkt im Code sichtbar.
Enums als Felder in Structs und als Array-Elemente:
import std.alloc;
enum State { Idle, Running, Paused, Stopped }
// Enum-Feld in einem alloc'd Puffer (Offset-Muster)
pub con TASK_SIZE: int64 := 24;
pub con TASK_STATE: int64 := 0; // State als int64 gespeichert
pub con TASK_ID: int64 := 8;
pub con TASK_PRIO: int64 := 16;
fn TaskCreate(id: int64, prio: int64): int64 {
var t: int64 := alloc(TASK_SIZE);
if (t == 0) { return 0; }
poke64(t + TASK_STATE, State::Idle as int64);
poke64(t + TASK_ID, id);
poke64(t + TASK_PRIO, prio);
return t;
}
fn TaskGetState(t: int64): State {
return peek64(t + TASK_STATE) as State;
}
fn TaskSetState(t: int64, s: State): void {
poke64(t + TASK_STATE, s as int64);
}
fn TaskIsRunning(t: int64): bool {
return TaskGetState(t) == State::Running;
}
Enums sind ein bevorzugtes Mittel in sicherheitskritischem Code, weil sie den Zustandsraum explizit und abgeschlossen definieren:
@flight_crit(DAL-A)
enum EngineState {
Off = 0,
Starting = 1,
Idle = 2,
Running = 3,
Overspeed = 4,
Shutdown = 5
}
@flight_crit(DAL-A)
fn EngineTransition(current: EngineState, cmd: EngineCommand): EngineState {
// Vollständige Zustandsmaschine — kein default, alle Kombinationen explizit
return match (current) {
case EngineState::Off => match (cmd) { ... };
case EngineState::Starting => match (cmd) { ... };
case EngineState::Idle => match (cmd) { ... };
case EngineState::Running => match (cmd) { ... };
case EngineState::Overspeed => EngineState::Shutdown; // immer herunterfahren
case EngineState::Shutdown => EngineState::Off;
};
}
| Eigenschaft | Enum | int64-Konstanten |
|---|---|---|
| Compiler-Exhaustivitätsprüfung | ✅ Ja | ❌ Nein |
| Typsicherheit im Parameter | ✅ Ja | ❌ Nein (jede int64 passt) |
| Dokumentation im Code | ✅ Explizite Namen | Eingeschränkt |
| Gültigkeitsbereich | Pro Enum getrennt | Global |
| DO-178C geeignet | ✅ Empfohlen für Zustände | Bedingt |
| Frage | Antwort |
|---|---|
| Basistyp | int64 (immer) |
| Zugriffssyntax | EnumName::Wert |
| Methoden | Nicht unterstützt |
| Enum → int64 | val as int64 |
| int64 → Enum | intVal as EnumTyp (unsafe — Wert unklar) |
| match-Exhaustivität | Pflicht ohne default |
| In Safety-Code | Enums für alle Zustände bevorzugen, kein default |
| Bit-Flags | Werte als Zweierpotenzen; kombinieren als int64 |
→ Pattern Matching — match, Guards, Exhaustivität
→ Datentypen — vollständige Typübersicht
→ Typ-Aliase und Typumwandlung (as, is)
Letzte Aktualisierung: 2026-06-05