Dieser Artikel baut Gos if von Grund auf: erst die einfachste Form mit einer Bedingung, dann das Bauen von Bedingungen aus Vergleichen und boolescher Logik, dann else und else if. Darauf folgt Gos Besonderheit — die Init-Klausel, in der du direkt vor der Bedingung eine Variable einführst, deren Sichtbarkeit auf die Verzweigung beschränkt bleibt. Mit dieser Grundlage erklären sich die drei Stellen, an denen Go-Code die Form überall nutzt: comma-ok-Checks, das Guard-Clause-Muster im Error-Handling und sauberes Scoping ohne Variablen-Ballast. Am Ende stehen die Stolperfallen, die in Reviews regelmäßig auffallen.

Die einfachste Form — eine Bedingung, ein Block

Hinter dem Schlüsselwort if steht eine Bedingung, danach ein Block in geschweiften Klammern. Ist die Bedingung wahr, läuft der Block — sonst wird er übersprungen, und das Programm macht hinter der schließenden Klammer weiter. So weit verhält sich Go wie jede andere Sprache.

Zwei Regeln gelten in Go strikt und überraschen Umsteiger aus C, Java oder JavaScript: Es gibt keine Klammern um die Bedingung, und die geschweiften Klammern um den Block sind Pflicht — auch bei einer einzigen Anweisung.

Go if_basic.go
package main

import "fmt"

func main() {
    temperature := 22

    // Eine Bedingung, ein Block.
    if temperature > 18 {
        fmt.Println("angenehm warm")
    }

    // Die Bedingung MUSS ein bool sein — Go kennt kein "truthy".
    loggedIn := false
    if loggedIn {
        fmt.Println("willkommen zurück")
    }

    fmt.Println("Programm läuft weiter")
}
Output
angenehm warm
Programm läuft weiter

Der entscheidende Punkt für neue Go-Lerner steckt im Kommentar: Die Bedingung muss vom Typ bool sein. Go hat keine „truthy/falsy"-Semantik wie Python oder JavaScript. Ein if 1 { ... } oder if "text" { ... } ist kein wahrer Wert, sondern ein Compile-Fehler. Eine Zahl ist keine Bedingung — du musst sie zu einem Wahrheitswert machen, etwa mit if n != 0 { ... }. Diese Strenge wirkt anfangs umständlich, eliminiert aber eine ganze Klasse von Verwechslungs-Bugs: In Go steht in einem if immer sichtbar, was genau geprüft wird.

Bedingungen bauen — Vergleiche und boolesche Logik

Wenn die Bedingung ein bool sein muss, ist die nächste Frage: Wie kommt man zu einem? Zwei Quellen liefern Wahrheitswerte. Erstens die Vergleichsoperatoren, die zwei Werte gegeneinander prüfen und true oder false ergeben. Zweitens die logischen Operatoren, die solche Teil-Bedingungen zu einer größeren verknüpfen.

OperatorBedeutungBeispielErgebnis
==gleichage == 18bool
!=ungleichname != ""bool
< <=kleiner / kleiner-gleichi < len(xs)bool
> >=größer / größer-gleichscore >= 60bool
&&logisches Unda > 0 && b > 0bool
||logisches Oderx < 0 || x > 100bool
!Negation!hasTicketbool

&& und || werten von links nach rechts aus und brechen ab, sobald das Ergebnis feststeht — die Kurzschluss-Auswertung. Steht beim && links schon false, wird der rechte Teil nicht mehr angefasst; steht beim || links schon true, ebenfalls nicht. Damit kannst du links eine billige oder schützende Prüfung stellen und rechts eine teure oder gefährliche, die nur unter der linken Bedingung laufen darf.

Go conditions.go
package main

import "fmt"

func main() {
    age := 25
    hasTicket := true

    // Ein einzelner Vergleich liefert bereits ein bool.
    if age >= 18 {
        fmt.Println("volljährig")
    }

    // && verlangt, dass beide Teile wahr sind.
    if age >= 18 && hasTicket {
        fmt.Println("Einlass gewährt")
    }

    // ! kehrt einen Wahrheitswert um.
    if !hasTicket {
        fmt.Println("bitte Ticket kaufen")
    }

    // Kurzschluss: ist age < 0 schon true, wird der rechte
    // Teil nicht mehr geprüft — und umgekehrt.
    if age < 0 || age > 120 {
        fmt.Println("unplausibles Alter")
    }
}
Output
volljährig
Einlass gewährt

Ein praktisches Beispiel für den Nutzen des Kurzschlusses ist die Index-Prüfung vor einem Zugriff: if i < len(xs) && xs[i] == target. Der linke Teil garantiert, dass i ein gültiger Index ist; nur dann wird der rechte Teil xs[i] ausgewertet. Dreht man die Reihenfolge um, knallt es bei einem zu großen i mit einer Panic. Die Reihenfolge der Operanden ist hier also nicht beliebig, sondern trägt Bedeutung.

else und else if — Alternativen abdecken

Bisher hat if nur entschieden, ob ein Block läuft. Mit else hängst du einen zweiten Block an, der genau dann läuft, wenn die Bedingung false war — entweder das eine oder das andere. Reicht das nicht, weil mehrere sich ausschließende Fälle abzudecken sind, kettest du mit else if weitere Bedingungen hintereinander. Go prüft sie von oben nach unten und nimmt den ersten Zweig, dessen Bedingung wahr ist; ein abschließendes else fängt alles Übrige.

Go else_if.go
package main

import "fmt"

func main() {
    score := 72

    if score >= 90 {
        fmt.Println("Note: sehr gut")
    } else if score >= 75 {
        fmt.Println("Note: gut")
    } else if score >= 60 {
        fmt.Println("Note: befriedigend")
    } else {
        fmt.Println("Note: nicht bestanden")
    }
}
Output
Note: befriedigend

Beachte die Reihenfolge: score ist 72. Die erste Bedingung (>= 90) ist falsch, die zweite (>= 75) ebenfalls, die dritte (>= 60) trifft zu — also wird „befriedigend" gedruckt und der Rest der Kette übersprungen. Würde man die Schwellen umgekehrt sortieren (kleinste zuerst), fiele jeder Wert sofort in den ersten Zweig — ein klassischer Anfängerfehler bei else if-Ketten mit Bereichsgrenzen.

else if ist kein eigenes Schlüsselwort. Go kennt nur if und else. Was wie else if aussieht, ist ein else, dem direkt ein neues, vollständiges if folgt. Deshalb lässt sich die Kette beliebig fortsetzen — und deshalb hat sie nur einen einzigen Geltungsbereich, sobald eine Init-Klausel ins Spiel kommt (siehe Abschnitt 05).

Sobald eine else if-Kette länger als zwei oder drei Zweige wird, ist meist ein switch die klarere Wahl.

Die Init-Klausel — die Variable, die nur im if lebt

Oft brauchst du vor einer Prüfung noch eine kurze Berechnung oder einen Funktionsaufruf, dessen Ergebnis nur für die Prüfung relevant ist. Naiv schreibt man das in zwei Zeilen:

Go without_init.go
// Hilfsvariable vor dem if — sie lebt danach im ganzen
// Funktions-Scope weiter, obwohl niemand sie mehr braucht.
doubled := n * 2
if doubled > 100 {
    fmt.Println("groß:", doubled)
}
// doubled ist hier immer noch sichtbar — unnötiger Ballast.

Das funktioniert, hat aber einen Nachteil: doubled bleibt nach dem if im gesamten Funktions-Scope sichtbar, obwohl es nur für diese eine Prüfung gedacht war. In langen Funktionen sammeln sich so Variablen an, die nichts mehr tun, aber den Namensraum belegen und beim Lesen mitgedacht werden müssen.

Die Init-Klausel löst das: Du darfst vor der Bedingung — abgetrennt durch ein Semikolon — ein kurzes Statement setzen. Die dort deklarierte Variable gehört dann zum if und ist nur darin sichtbar.

Go if_init.go
package main

import "fmt"

func main() {
    n := 60

    // Init-Klausel:  Statement ; Bedingung
    // doubled entsteht direkt im if und lebt nur dort.
    if doubled := n * 2; doubled > 100 {
        fmt.Println("groß:", doubled)
    }

    // Hier ist doubled nicht mehr sichtbar — der Scope bleibt sauber.
    // fmt.Println(doubled) // Compile-Fehler: undefined: doubled
}
Output
groß: 120

Das Semikolon ist hier Pflicht und trennt die zwei Teile: links das Init-Statement (doubled := n * 2), rechts die Bedingung (doubled > 100). Verwechsle es nicht mit einem Komma — ein Komma würde eine Mehrfachzuweisung bedeuten, kein Trennzeichen. Formal definiert die Go-Spezifikation das so:

EBNF IfStmt (Go-Spec)
IfStmt = "if" [ SimpleStmt ";" ] Expression Block [ "else" ( IfStmt | Block ) ] .

Das SimpleStmt in eckigen Klammern ist die optionale Init-Klausel. „Simple" heißt: ein einzelnes, einfaches Statement — am häufigsten eine Kurz-Deklaration mit :=, daneben aber auch eine Zuweisung mit =, ein Funktionsaufruf oder ein Inkrement wie i++. Verboten sind ganze Blöcke, ein weiteres if/for/switch, return, defer oder go. Die Abfolge ist dabei strikt festgelegt: Erst läuft das Init-Statement, dann wird die Bedingung ausgewertet, dann gegebenenfalls der Body. Das wird in den folgenden Abschnitten an mehreren Stellen wichtig.

Geltungsbereich — wo die Init-Variable lebt

Der Geltungsbereich der Init-Variable ist präzise definiert. Die Spezifikation formuliert es knapp:

Each if, for, and switch statement is considered to be in its own implicit block.

Übersetzt heißt das: Jedes if öffnet einen unsichtbaren Block, der die Init-Klausel und die gesamte if-else if-else-Kette umschließt. Eine in der Init-Klausel deklarierte Variable ist deshalb in jedem Zweig der Kette sichtbar — und endet mit der schließenden Klammer des letzten Zweigs. Danach existiert sie nicht mehr.

Go if_scope.go
package main

import "fmt"

func main() {
    if x := 10; x > 5 {
        fmt.Println("groß, x =", x) // sichtbar
    } else if x < 0 {
        fmt.Println("negativ, x =", x) // immer noch dasselbe x
    } else {
        fmt.Println("klein, x =", x) // auch hier dasselbe x
    }

    // x ist hier nicht mehr im Scope.
    // fmt.Println(x) // Compile-Fehler: undefined: x
}
Output
groß, x = 10

Die Variable lebt damit genau dort, wo sie ihren Wert braucht, und verschmutzt den umgebenden Funktions-Scope nicht. Aus dem Namen wird ein lokales, kurzlebiges Detail statt eines Mitbewohners der ganzen Funktion — der Hauptgrund, warum die Init-Form in Reviews bevorzugt wird.

Ein Detail, das erfahrene Leser kennen sollten und das aus dem „eigenen Block" jedes Zweigs folgt: Der Body eines else-Zweigs ist ein eigener, verschachtelter Block. Dort darfst du eine neue Variable mit demselben Namen deklarieren — sie überdeckt dann die aus der Init-Klausel. Das nennt sich Shadowing, ist legal, aber fast immer ein Versehen:

Go if_else_shadow.go
package main

import "fmt"

func main() {
    if x := 10; x > 5 {
        fmt.Println("if-Body, x =", x)
    } else {
        x := -1 // NEUE Variable — überdeckt das äußere x
        fmt.Println("else-Body, x =", x)
    }
}
Output
if-Body, x = 10

Absichtliches Shadowing dieser Art ist selten nötig. Begegnet es dir unbeabsichtigt, ist es meist die Wurzel eines Bugs — der Analyzer go vet -vettool=shadow macht solche Fälle sichtbar.

comma-ok — der wichtigste Einsatzort

Drei Stellen in Go liefern ein Wertepaar zurück: einen Wert und einen begleitenden bool, der angibt, ob der Wert gültig ist. Das sind Map-Lookups, Channel-Receives und Type Assertions — das comma-ok-Muster. Alle drei passen in die Init-Klausel, weil dort beide Variablen entstehen und der bool direkt als Bedingung dient.

Go comma_ok.go
package main

import "fmt"

func main() {
    users := map[string]int{"alice": 30, "bob": 25}

    // (1) Map-Lookup: ok ist true, wenn der Key existiert
    if age, ok := users["alice"]; ok {
        fmt.Println("alice ist", age)
    }

    // Negierte Variante — der Key fehlt
    if _, ok := users["carol"]; !ok {
        fmt.Println("carol unbekannt")
    }

    // (2) Channel-Receive: ok ist false, wenn der Channel leer
    //     und geschlossen ist
    ch := make(chan int, 1)
    ch <- 42
    close(ch)
    if v, ok := <-ch; ok {
        fmt.Println("aus Channel:", v)
    }

    // (3) Type Assertion: ok ist true, wenn der Typ passt
    var value any = "hallo"
    if s, ok := value.(string); ok {
        fmt.Println("ist string:", s, "- Länge", len(s))
    }
}
Output
alice ist 30
carol unbekannt
aus Channel: 42
ist string: hallo - Länge 5

Die Init-Form passt hier aus drei Gründen. Erstens lebt der prüfende ok genau in der Verzweigung, in der er gebraucht wird, und nicht eine Zeile länger. Zweitens ist der gefundene Wert (age, v, s) eng an seine Gültigkeit gekoppelt: Sein begrenzter Scope erinnert daran, dass er außerhalb der Verzweigung nur den Zero Value enthielte. Drittens spart die Form den separaten Zwei-Zeiler aus Deklaration und anschließendem if. comma-ok ist damit der häufigste Grund, warum die Init-Form in echtem Go-Code auftaucht.

Guard Clauses — linear statt verschachtelt

Der zweite Einsatzort ist das Error-Handling. Go bevorzugt einen Stil, den die offiziellen Code-Review-Richtlinien „indent error flow" nennen — die Guard Clause: Prüfe zuerst alle Fehler- und Sonderfälle, kehre beim ersten Problem sofort zurück und schreibe den erfolgreichen Pfad danach geradlinig und ohne Einrückung. Statt den Erfolgsfall in ein else zu verschachteln, steigt man bei Problemen früh aus.

Das folgende Beispiel ist bewusst praxisnah: Es validiert die Eingaben eines Registrierungs-Formulars und kombiniert dabei alles aus diesem Artikel — comma-ok beim Map-Lookup, die Init-Form und mehrere hintereinandergestellte Guard Clauses.

Go signup_validation.go
package main

import (
    "errors"
    "fmt"
    "strings"
)

// validateSignup prüft die Felder eines Registrierungs-Formulars.
// Jede Regel ist eine Guard Clause: beim ersten Verstoß raus.
func validateSignup(form map[string]string) error {
    name, ok := form["name"]
    if !ok || strings.TrimSpace(name) == "" {
        return errors.New("Name fehlt")
    }

    email, ok := form["email"]
    if !ok || !strings.Contains(email, "@") {
        return fmt.Errorf("ungültige E-Mail: %q", email)
    }

    // Init-Form: pw wird nur für diese eine Prüfung gebraucht.
    if pw := form["password"]; len(pw) < 8 {
        return fmt.Errorf("Passwort zu kurz: %d Zeichen", len(pw))
    }

    return nil // alle Prüfungen bestanden
}

func main() {
    forms := []map[string]string{
        {"name": "Alice", "email": "alice@example.com", "password": "supergeheim"},
        {"name": "", "email": "x@y.z", "password": "12345678"},
        {"name": "Bob", "email": "kein-at", "password": "geheim12"},
        {"name": "Carol", "email": "carol@example.com", "password": "kurz"},
    }

    for _, f := range forms {
        if err := validateSignup(f); err != nil {
            fmt.Println("abgelehnt:", err)
            continue
        }
        fmt.Println("akzeptiert:", f["name"])
    }
}
Output
akzeptiert: Alice
abgelehnt: Name fehlt
abgelehnt: ungültige E-Mail: "kein-at"
abgelehnt: Passwort zu kurz: 4 Zeichen

Der erfolgreiche Pfad — das return nil — liegt linear ganz unten, ohne Einrückung. Jede Fehlerprüfung ist eine eigene, flache Verzweigung; nichts verschachtelt sich. In der main-Funktion wiederholt sich das Muster: if err := validateSignup(f); err != nil hält den Fehler über die Init-Form genau in der prüfenden Verzweigung, und continue springt zum nächsten Formular, statt den Rest der Schleife einzurücken.

In keiner dieser Verzweigungen steht ein else. Idiomatisches Go schreibt fast nie if err != nil { ... } else { weiterarbeiten }. Stattdessen kehrt der Fehlerzweig zurück, und „weiterarbeiten" steht danach — flacher und besser lesbar. Bei jedem zusätzlichen Sonderfall wächst der Code nach unten statt nach rechts.

Wann die Init-Form nicht passt

Die Init-Klausel schadet in einem Fall: wenn der berechnete Wert nach der Verzweigung noch gebraucht wird. Weil die Init-Variable mit der if-Kette stirbt, ist sie anschließend unzugänglich, und du müsstest sie erneut berechnen oder erneut lesen. Das tritt beim Error-Handling von Funktionen auf, deren Rückgabewert weiterverwendet wird:

Go anti_pattern.go
// ANTI-PATTERN: Die Init-Form sperrt den Wert in die Verzweigung.
if data, err := readConfig(); err != nil {
    log.Fatal(err)
}
// data ist hier nicht mehr sichtbar — der gelesene Wert ist verloren.

// BESSER: Deklaration davor, dann eine einfache Guard Clause.
data, err := readConfig()
if err != nil {
    log.Fatal(err)
}
useData(data) // jetzt sichtbar und nutzbar

Brauchst du den Wert nur für die Prüfung selbst, gehört die Deklaration in die Init-Klausel. Brauchst du ihn auch danach, gehört sie aus dem if heraus, eine Zeile davor. comma-ok bleibt davon unberührt — dort ist der ok per Definition nur für die Verzweigung gedacht, und der Wert wird im zugehörigen Zweig konsumiert:

SituationForm
Variable nur in der if-Kette gebrauchtInit-Form
Variable danach noch nötigDeklaration davor, dann if cond { ... }
comma-ok-Muster (v, ok := ...)Init-Form
Funktions-Rückgabewert wird nach der Prüfung gebraucht:= davor, darunter if err != nil { return ... }
Komplexer Ausdruck aus mehreren SchrittenStatements davor, das if einfach halten

Eine Feinheit der Auswertung — das Init läuft genau einmal

In einer if-else if-else-Kette wird das Init-Statement nur ein einziges Mal ausgewertet — vor dem ersten Test. Es läuft nicht erneut für jeden else if. Das folgt aus Abschnitt 03: else if ist nur ein else mit verschachteltem if, und die Init-Klausel gehört zum äußersten if. Wer hier Seiteneffekte pro Zweig erwartet, baut leise einen Bug.

Go init_once.go
package main

import "fmt"

var calls int

func nextValue() int {
    calls++
    return calls
}

func main() {
    if v := nextValue(); v == 1 {
        fmt.Println("erste Branche:", v)
    } else if v == 2 {
        fmt.Println("zweite Branche:", v)
    } else {
        fmt.Println("else:", v)
    }
    fmt.Println("Aufrufe insgesamt:", calls)
}
Output
erste Branche: 1
Aufrufe insgesamt: 1

nextValue() läuft exakt einmal, nicht pro Test — calls steht am Ende auf 1, nicht auf 3. Für den Normalfall ist das richtig: Du berechnest einen Wert einmal und prüfst ihn mehrfach. Zum Bug wird es, wenn du erwartest, der Aufruf liefere bei jedem else if einen frischen Wert.

Ein zweiter Punkt betrifft die Reihenfolge: Das Init-Statement läuft auch dann, wenn die Bedingung anschließend false ist und der Body übersprungen wird. Hat das Statement einen Seiteneffekt — ein Logging, einen Zähler, einen Channel-Send —, passiert dieser unabhängig vom Ausgang der Bedingung.

Zwei Syntax-Fallen für Umsteiger

Zwei Eigenheiten bringen Umsteiger aus C, Java oder JavaScript regelmäßig zum Stolpern. Die erste betrifft die Klammern um die Bedingung: Go verzichtet konsequent darauf. Sie sind nicht verboten — gofmt lässt sie stehen —, aber der Style-Guide und jede ernsthafte Codebase schreiben ohne. Die Gewohnheit aus C/Java sollte man ablegen, weil Inkonsistenz im Projekt unnötig stört.

Go parens.go
// Idiomatisches Go
if x > 5 && y < 10 {
    // ...
}

// Legal, aber unidiomatisch — sieht nach C aus
if (x > 5 && y < 10) {
    // ...
}

Die zweite Falle tritt seltener auf, kostet aber Zeit, wenn die Fehlermeldung verwirrt. Wer ein Composite Literal wie Point{0, 0} direkt in die Bedingung schreibt, bringt den Parser in die Klemme: Er kann nicht entscheiden, ob die geschweifte Klammer zum Literal gehört oder schon den Body öffnet. Dieselbe Mehrdeutigkeit gilt für for und switch.

Go composite_ambiguity.go
package main

type Point struct{ X, Y int }

func main() {
    origin := Point{0, 0}

    // FEHLER: Der Compiler liest Point{ als Block-Anfang.
    // if origin == Point{0, 0} { ... }

    // KORREKT: Klammern um das Composite Literal.
    if origin == (Point{0, 0}) {
        println("origin")
    }

    // ALTERNATIVE: vorher einer Variable zuweisen.
    zero := Point{0, 0}
    if origin == zero {
        println("origin via Variable")
    }
}

Beide Fallen lösen sich gleich: die fragliche Konstruktion in eine eigene, benannte Variable davorziehen. Das räumt die Composite-Literal-Ambiguität aus und entzerrt ebenso einen zu komplexen Ausdruck in der Bedingung.

Häufige Stolperfallen

Die Bedingung muss ein bool sein — kein „truthy“.

Go hat keine „truthy/falsy"-Semantik. if n { ... } mit einem int ist ein Compile-Fehler, kein impliziter Wahrheits-Check. Schreibe explizit, was du meinst: if n != 0 { ... }, if s != "" { ... }, if err != nil { ... }. Das wirkt geschwätziger, macht aber jede Bedingung selbsterklärend.

Shadowing in if-Init mit := — die häufigste Falle.

Wer x, err := foo() in einer if-Init schreibt, obwohl err schon im äußeren Scope existiert, legt eine neue err-Variable an, die mit der if-Kette stirbt. Die äußere bleibt unverändert. Beim reinen comma-ok-Check im Body unproblematisch — greifst du später auf die äußere Variable zu, bricht es subtil. Den shadow-Analyzer aktivieren.

Init-Form sperrt den Wert ein — danach unzugänglich.

if data, err := load(); err != nil { ... } macht data nach der Verzweigung unsichtbar. Willst du den Wert weiterverwenden, gehört das := aus dem if heraus — sonst musst du ihn doppelt lesen oder neu berechnen. Faustregel: Wert nur für die Prüfung → Init-Form; Wert auch danach → Deklaration davor.

Init-Statement läuft einmal für die ganze if-else-Kette.

if v := compute(); v == 1 { ... } else if v == 2 { ... } ruft compute() exakt einmal auf — nicht pro Zweig. Wer Seiteneffekte pro else if erwartet, baut leise einen Bug. Außerdem: Das Init läuft auch dann, wenn die Bedingung false ist und der Body übersprungen wird.

Geschweifte Klammern sind Pflicht — auch bei Einzeilern.

if x > 0 doSomething() ist ein Syntax-Fehler. if x > 0 { doSomething() } ist das Minimum. Das hat Go bewusst von C übernommen, um die berüchtigte „goto fail"-Klasse von Bugs zu vermeiden — den versteckten Statement-Body hinter einem if ohne Block.

else-Body ist ein eigener Block — Variablen lassen sich überdecken.

Im else-Zweig darfst du x := -1 schreiben, auch wenn die Init-Klausel des if schon ein x deklariert hat. Das innere überdeckt das äußere. Legal, aber fast immer ein Versehen — ein gleicher Name im Sub-Block sollte Alarm auslösen.

else if ist ein syntaktischer Trick, kein Keyword.

Die Spec kennt nur if und elseelse if ist else <neues if>. Konsequenz: Es gibt keinen separaten Scope für „else if". Die Init-Variable aus dem ersten if ist in allen nachfolgenden else if- und else-Zweigen sichtbar.

Composite Literal in der Bedingung braucht Klammern.

if p == Point{0, 0} { ... } ist ein Syntax-Fehler — der Compiler liest Point{ als Block-Anfang. Lösung: if p == (Point{0, 0}) { ... } oder vorher zero := Point{0, 0}; if p == zero { ... }. Dieselbe Falle gilt bei for und switch.

Lange else if-Ketten gehören in switch.

Drei oder mehr else if sind ein Refactoring-Signal. switch { case a: ... ; case b: ... } (ohne Tag) liest sich besser, gruppiert die Fälle klar und erlaubt fallthrough. Auch der Type Switch (switch v := x.(type) { ... }) ersetzt manuelle if _, ok := x.(T); ok-Kaskaden.

Klammern um die Bedingung sind unidiomatisch.

if (x > 0) { ... } läuft, aber niemand schreibt das in Go. gofmt entfernt sie nicht, doch jeder Reviewer markiert sie. Die Gewohnheit aus C/Java ablegen — sinnvoll sind Klammern nur dort, wo die Präzedenz nicht offensichtlich ist (if (a || b) && c) oder zur Auflösung der Composite-Literal-Ambiguität.

Weiterführende Ressourcen

Externe Quellen

/ Weiter

Zurück zu Kontrollstrukturen

Zur Übersicht