Menu

Golang if else: Syntax, Init-Anweisungen und if err != nil

So funktionieren if, else if und else in Go: keine Klammern, Pflicht-Klammern um den Block, die if-Anweisung mit Init-Klausel und ihr Scope, das Idiom if err != nil und frühe Returns statt tiefer Verschachtelung.

Diese Seite enthält ausführbare Editoren - bearbeiten, ausführen und Ausgabe sofort sehen.

Das if von Go hat keine Klammern um die Bedingung, verlangt immer geschweifte Klammern und kann mit einer kurzen Anweisung beginnen, die Variablen mit Scope auf das if deklariert.

Die Bedingungen werden von oben geprüft, und der erste wahre Zweig läuft. else if und else sind optional.

Syntaxregeln

Drei Regeln weichen von C, Java und JavaScript ab:

  1. Keine Klammern um die Bedingung. if (x > 5) kompiliert, aber gofmt entfernt die Klammern.
  2. Geschweifte Klammern sind Pflicht, auch für eine einzige Anweisung. Ein if x > 5 return ohne Klammern gibt es nicht.
  3. else steht in derselben Zeile wie die schließende Klammer. Go fügt nach einer } am Zeilenende ein Semikolon ein, daher scheitert das hier:
if x > 5 {
	fmt.Println("big")
}
else {
	fmt.Println("small")
}
syntax error: unexpected keyword else, expected }

Schreib } else { in eine Zeile.

Die Bedingung muss ein bool sein. Go behandelt 0, "" oder nil nicht als falsch, also kompilieren if count {} und if name {} nicht. Vergleiche explizit: if count > 0, if name != "", if user != nil.

Bedingungen verknüpfst du mit && (und), || (oder) und ! (nicht). Sowohl && als auch || werten kurzschließend aus, was Nil-Prüfungen sicher macht:

if user != nil && user.IsAdmin() {
	// user.IsAdmin() is only called when user is not nil
}

if mit einer Init-Anweisung

Ein if kann vor der Bedingung eine kurze Anweisung ausführen, getrennt durch ein Semikolon. Darin deklarierte Variablen sind in jedem Zweig dieses if sichtbar und danach nirgends mehr:

Das Muster hält kurzlebige Variablen aus dem umgebenden Scope heraus. Es taucht ständig bei Map-Lookups (v, ok := m[k]), Type Assertions (s, ok := v.(string)) und Fehlern auf.

Die Kehrseite: Brauchst du den Wert nach dem if, deklarier ihn vorher. Ein häufiger Fehler ist, ein Ergebnis in die Init-Anweisung zu packen und es dann weiter unten benutzen zu wollen.

Das Idiom if err != nil

Funktionen, die fehlschlagen können, geben als Letztes einen error zurück. Prüf ihn sofort, behandle ihn oder gib ihn zurück, und mach mit dem Normalfall ohne Einrückung weiter:

Nach if err != nil { return ... } steht kein else. Im Go-Stil behandelst du den Fehler, kehrst zurück und lässt den normalen Ablauf am linken Rand. Die Seite zur Fehlerbehandlung erklärt das Wrapping und die Prüfung von Fehlertypen.

Frühe Returns statt Verschachtelung

Tief verschachtelte if-Blöcke sind schwer zu lesen. Dreh die Bedingungen um und kehr früh zurück; jede Prüfung liest sich dann wie ein Guard:

// Nested
func canCheckout(u *User, cart *Cart) bool {
	if u != nil {
		if u.Verified {
			if len(cart.Items) > 0 {
				return true
			}
		}
	}
	return false
}

// Guards
func canCheckout(u *User, cart *Cart) bool {
	if u == nil || !u.Verified {
		return false
	}
	if len(cart.Items) == 0 {
		return false
	}
	return true
}

Go-Programmierer nennen das: den Happy Path linksbündig halten. Linter wie revive markieren ein else nach einem Block, der mit return endet, weil das else nur unnötige Einrückung bringt.

if/else oder switch

Eine lange Kette von else if, die einen Wert gegen mehrere Fälle testet, liest sich als switch besser. Ein switch ohne Ausdruck ersetzt eine if/else if-Kette mit beliebigen Bedingungen:

switch {
case score >= 90:
	return "A"
case score >= 80:
	return "B"
default:
	return "F"
}

Nimm if für einen oder zwei Zweige und switch ab drei.

Kein ternärer Operator

Go hat kein cond ? a : b. Weise mit if zu:

label := "odd"
if n%2 == 0 {
	label = "even"
}

Die Seite zum ternären Operator erklärt warum und zeigt die Alternativen.

Häufige Fehler

  • Shadowing mit :=. if x, err := f(); err == nil { ... } deklariert ein neues x nur für das if. Ein äußeres x wird nicht aktualisiert.
  • Zuweisung in der Bedingung. if x = 5 {} ist ein Compilerfehler (cannot use assignment x = 5 as value), kein stiller Bug wie in C. Nimm ==.
  • Floats mit == vergleichen. if total == 0.3 schlägt bei berechneten Werten fehl. Vergleiche mit einer Toleranz.
  • Den falschen Fehler prüfen. Nach a, err := f() und b, err := g() achte darauf, dass jedes if err != nil direkt nach seinem Aufruf steht.

Häufig gestellte Fragen

Wie schreibt man if else in Go?

Ohne Klammern um die Bedingung und immer mit geschweiften Klammern:

if x > 10 {
	fmt.Println("big")
} else if x > 5 {
	fmt.Println("medium")
} else {
	fmt.Println("small")
}

else muss in derselben Zeile stehen wie die schließende Klammer des vorherigen Blocks.

Was ist eine if-Anweisung mit Init-Anweisung in Go?

Eine kurze Anweisung vor der Bedingung, getrennt durch ein Semikolon: if n, err := strconv.Atoi(s); err != nil { ... }. Dort deklarierte Variablen existieren nur innerhalb des if und seiner Zweige else if und else. So sickern sie nicht in den Rest der Funktion durch.

Kann ich in Go ein einzeiliges if schreiben?

Nicht ohne geschweifte Klammern. if ok return und if (ok) x = 1; sind Syntaxfehler. Die kürzeste Form ist if ok { return }, und gofmt setzt den Rumpf in eine eigene Zeile. Go hat auch keinen ternären Operator, also braucht ein bedingter Wert ein if/else oder eine kleine Hilfsfunktion.

Warum steht in Go überall if err != nil?

Go hat keine Exceptions. Funktionen, die fehlschlagen können, geben als letztes Ergebnis einen error zurück, und der Aufrufer prüft ihn sofort mit if err != nil. Die Wiederholung ist der Preis dafür, dass jede Fehlerstelle genau dort sichtbar ist, wo sie passiert.

Coddy programming languages illustration

Lerne mit Coddy zu programmieren

LOS GEHT'S