Ein switch vergleicht einen Wert mit einer Liste von Cases und führt den ersten Treffer aus. Anders als in C, Java und JavaScript fällt ein Go-Case nicht in den nächsten durch, es gibt also kein break, das du vergessen könntest.
Die Cases werden von oben nach unten geprüft, und nur der erste passende läuft. default läuft, wenn nichts passt; es ist optional und kann überall in der Liste stehen, per Konvention steht es aber am Ende.
Mehrere Werte pro Case
case "sat", "sun": passt auf beide Werte. So drückt Go aus, was C mit gestapelten leeren Cases macht. Jeder vergleichbare Typ funktioniert: Strings, Zahlen, Runes, Booleans, Pointer und benannte Typen wie Enums:
Zwei Cases mit demselben konstanten Wert sind ein Compilerfehler:
./main.go:10:7: duplicate case 1 (constant of type int) in expression switch
./main.go:8:7: previous case
switch ohne Bedingung
Lässt du den Ausdruck weg, wird jeder Case zu einem booleschen Test. Das ist die sauberere Form einer langen if/else if-Kette in Go:
switch { ist die Kurzform für switch true {. Da der erste wahre Case gewinnt, zählt die Reihenfolge: bmi < 25 wird nur erreicht, wenn bmi < 18.5 falsch war, also kann jeder Case davon ausgehen, dass die darüber nicht gepasst haben.
switch mit Init-Anweisung
Wie if kann ein switch mit einer kurzen Anweisung beginnen. Dort deklarierte Variablen gelten nur im switch:
Die Init-Anweisung lässt sich auch mit einem switch ohne Ausdruck kombinieren: switch n := len(items); { case n == 0: ... }.
fallthrough
Willst du tatsächlich im nächsten Case weitermachen, schreib fallthrough als letzte Anweisung eines Case. Es übergibt die Kontrolle an den Rumpf des nächsten Case, ohne dessen Bedingung auszuwerten:
Level 2 gibt write und dann read aus und sammelt die Berechtigungen nach unten hin auf. Die Bedingungen der späteren Cases werden nicht geprüft: Nach fallthrough aus case 2 läuft case 1, obwohl level 2 ist.
Regeln für fallthrough:
- Es muss die letzte Anweisung im Case sein.
- Im letzten Case darf es nicht stehen:
cannot fallthrough final case in switch. - In einem Type Switch ist es nicht erlaubt.
In der Praxis ist fallthrough in Go-Code selten. Mehrere Werte pro Case decken den üblichen Bedarf, und explizite Funktionsaufrufe sind meist klarer als eine Kette von fallthroughs.
break in einem switch
break in einem Case verlässt den switch. Cases enden von selbst, also brauchst du es nur, um einen Case vorzeitig zu verlassen. Die Falle ist ein switch in einer Schleife:
Ohne das Label loop beendet break den switch, und die Schleife macht mit "c" weiter. continue dagegen bezieht sich immer auf die umschließende Schleife, da ein switch keine Schleife ist.
switch auf Typen
Ein Type Switch verzweigt nach dem dynamischen Typ eines Interface-Werts und nutzt dafür die spezielle Form v.(type):
In einem Case mit einem einzelnen Typ hat x diesen Typ (len(x) funktioniert im string-Case). In einem Case mit mehreren Typen behält x den Interface-Typ. Die Seite zu Type Assertions behandelt Type Switches und die Assertion v.(T) im Detail.
Was der switch von Go anders macht
| Verhalten | C, Java, JavaScript | Go |
|---|---|---|
| In den nächsten Case fallen | Standard | nur mit fallthrough |
break am Ende jedes Case | Pflicht | nicht nötig |
| Mehrere Werte pro Case | gestapelte leere Cases | case a, b, c: |
| Case-Werte | (meist) Konstanten | beliebiger Ausdruck, von oben nach unten ausgewertet |
| switch-Wert | Ganzzahltypen (C) | jeder vergleichbare Typ |
| Kein switch-Ausdruck | nicht erlaubt | switch { case cond: } |
Case-Ausdrücke müssen keine Konstanten sein. case limit(), max + 1: ist erlaubt; sie werden der Reihe nach ausgewertet, bis einer passt, also laufen spätere Ausdrücke unter Umständen nie.
Vollständigkeit
Go prüft nicht, ob ein switch über ein Enum jeden Wert abdeckt. Füg ein default hinzu, das bei unerwarteten Werten loggt, einen Fehler zurückgibt oder eine Panic auslöst, oder nutze den Linter exhaustive (Teil von golangci-lint), damit fehlende Cases beim Build gemeldet werden.
Häufig gestellte Fragen
Fällt ein switch in Go in den nächsten Case durch?
Nein. Ein Go-Case endet automatisch beim nächsten case; du schreibst nie break, um ihn zu stoppen. Soll die Ausführung im Rumpf des nächsten Case weitergehen, schreib fallthrough als letzte Anweisung des Case. Es springt bedingungslos, ohne die Bedingung des nächsten Case zu prüfen.
Wie prüfe ich in Go mehrere Werte in einem Case?
Liste sie durch Kommas getrennt auf: case "sat", "sun":. Der Case läuft, wenn der switch-Wert einem davon entspricht. Das ersetzt die gestapelten leeren Cases, die du in C oder Java schreiben würdest.
Was ist ein switch ohne Bedingung in Go?
switch { case x < 0: ...; case x == 0: ...; default: ... }. Ohne Ausdruck nach switch ist jeder Case eine boolesche Bedingung, und der erste wahre läuft. Das ist der idiomatische Ersatz für eine lange if/else if-Kette.
Was macht break in einem switch in Go?
Es beendet den switch, nicht eine umschließende for-Schleife. Das braucht man selten, da Cases von selbst enden, aber es überrascht alle, die break in einem switch in einer Schleife schreiben und erwarten, die Schleife zu verlassen. Dafür nimmst du ein break mit Label oder return.