Mit case expressions kannst du den Ablauf eines Programms aus einer Liste von Auswahlmöglichkeiten control the flow. Die Case-statement in Verse ist eine Möglichkeit, einen Wert gegen mehrere mögliche Werte zu testen (als ob du = verwenden würdest) und den Code basierend auf dem passenden Wert auszuführen.
Die Verwendung von Case-Ausdrücken kann in allen Arten von Anwendungen gefunden werden, z. B. in Spielen, in denen es einen nicht spielbaren Charakter gibt (NPC).
Zum Beispiel kannst du mit dem Guard Spawner-Gerät eine Wache spawnen, deren Patrouillenoption aktiviert ist. Nachdem du die Wache ins Spiel gespawnt hast, kann sie verschiedene Zustände annehmen: Leerlauf, Patrouille, Warnung, Angreifen und Sammeln. Ein übergeordnetes Zustandsübergangsdiagramm könnte dafür wie folgt aussehen:
Du kannst diese Zustandsübergänge im Spiel beobachten.
In diesem Video ist die Option „Patrouille“ des Wächters als Standardverhalten aktiviert.
Im Video wechselt der Wächter von der Patrouille der Wissenschaftsbasis zum Abbauen einiger Ressourcen. Dann entdeckt die Wache den Spieler, was die Wache in einen Alarmzustand versetzt (angezeigt durch das schwebende Fragezeichen), bevor sie in ihren Angriffszustand übergeht (angezeigt durch das schwebende Ausrufezeichen).
Abhängig davon, in welchem Zustand sich der Wächter befindet, zeigt er bestimmte Verhaltensweisen. Diese Verhaltensweisen sind in der Regel als functions kodiert, die called werden, wenn das Programm sich entscheidet, in einen bestimmten Zustand zu gehen.
Als Code könnte dieser übergeordnete Zustandsübergang der Wache wie folgt aussehen:
case(GuardStateVariable):
idle_state =>
RunIdleAnimation()
SearchPlayerCharacter()
harvest_state =>
GatherResources()
alert_state=>
RunAlertAnimation()
PlayAlertSound()
DisplayAlertUIElement()
Dieser case-Ausdruck ist ein Label, das dem Programm sagt, welche Funktionen ausgeführt werden sollen, wenn die Wache einen bestimmten Zustand erreicht.
In diesem Ausdruck ist der Patrouillenzustand der Wache der Standardfall, da eine Wache mit aktivierter Patrouille ihr Standardpatrouillenverhalten ausführen sollte.
Syntaktisch ist dies dasselbe wie:
expression0
case (test-arg-block):
label1 =>
expression1
label2 =>
expression2
_ =>
expression3 for the default case
expression4Jedes Muster im case-block, wie label1 und label2, muss die Form constant => block verwenden, wobei die constant ein integer, logic, string, char oder enum-Wert sein kann. Case-Anweisungen funktionieren also nur mit int, logic, string, char und Enums.
Struktur
Von der Struktur her führt der Verse-Case-Ausdruck Code aus, der auf der Eingabe des GuardStateVariable-Testargumentblocks basiert, und er funktioniert funktional genauso wie eine Reihe von if-Ausdrücken.
In diesem Beispiel führt das Verse-Programm expression3 aus, wenn GuardStateVariable in alert_state aufgelöst wird. Wenn das Programm patrol_state übergibt, springt Verse strukturell zum Standardfall und führt expression5 aus.
Fall mit anderem Kontrollfluss verwenden
Die Blöcke in einer Fall-Anweisung dürfen unterbrochen und fortgesetzt werden, wenn sich die Fall-Anweisung innerhalb einer Schleife befindet. Blöcke von Fall-Anweisungen dürfen auch aus der Funktion, in der sie stehen, zurückkehren.
Beispiel:
loop:
case (x):
42 => break
_ => {}Diese absurde Schleife wird entweder eine Endlosschleife, oder sofort beendet, wenn x = 42.
Ein weiteres Beispiel:
Foo(x : int) : int =
case (x):
100 => return 200
_ => return 100This example is equivalent to:
Foo(x : int) : int =
case (x):
100 => 200
_ => 100Das liegt daran, dass die Fall-Anweisung der letzte Ausdruck der Funktion ist.
Standardfall
Fall-Anweisungen, die keinen _=>-Fall (einen Standardfall) haben, werden fail, wenn keiner der Fälle übereinstimmt. Es ist in Ordnung, solche Fall-Anweisungen in failure contexts zu verwenden (z. B. in Funktionen mit dem Effekt decides).
Fall-Anweisungen, die mit allen Fällen einer Aufzählung übereinstimmen, sind nicht fehlerhaft, auch wenn sie keinen _=>-Fall haben.