Fallunterscheidungen

Fallunterscheidungen in einer Programmiersprache sind wie das Salz in der Suppe. Ohne geht’s nicht wirklich. Letztendlich ist ein Programm dazu da, auf unterschiedliche Eingaben unterschiedlich zu reagieren und nicht immer genau dasselbe zu machen.

Eine Fallunterscheidung in Go sieht aus wie in fast allen anderen Programmiersprachen:

package main

import "fmt"

func beispiel(zahl int) {
    if zahl <= 10 {
        fmt.Println("Die Zahl ist kleiner als oder gleich 10")
    }
}

func main() {
    beispiel(5)
}

also in der einfachen Form: if ‹ausdruck› ‹block›. Als Ausdruck wird ein boolescher Wert erwartet, muss also true oder false ergeben. Die einfache Form kann noch erweitert werden. Es können mehrere Fälle mit else abgefangen werden:

if zahl <= 10 {
    fmt.Println("Die Zahl ist kleiner als oder gleich 10")
} else if zahl < 20 {
    fmt.Println("Die Zahl ist größer als 10 aber kleiner als 20")
} else {
    fmt.Println("Die Zahl ist größer als oder gleich 20")
}

Wenn man sich die Abfragen genauer anschaut, scheint es, also ob ein Fehler in der Logik ist. Die zweite Bedingung überprüft, ob der Wert, der in zahl gespeichert ist, kleiner ist als 20. Im positiven Fall wird die Meldung ausgegeben, das die Zahl größer sei als 10, aber keiner als 20. Das steht im Widerspruch zur abgefragten Bedingung, die ja nur auf »kleiner 20« geprüft hat. Die Auflösung des Widerspruchs liegt darin, dass die Bedingungen von oben nach unten abgefragt werden, und durch das else nur dann ausgeführt werden, wenn die Bedingungen vorher nicht zutreffen. Das heißt für die zweite Bedingung, dass dort sowieso nur Werte überprüft werden, die in dem ersten Vergleich »durchfallen« und damit größer sind als 10.

Es gibt noch eine weitere Form der Fallunterscheidung. Diese hat in der »if-Zeile« einen einfachen Ausdruck:

package main

import "fmt"

func leseZahl() int {
    // Hier könnte der Anwender eine Zahl eingeben
    // Im Beispiel geben wir aber immmer diesebe
    // Zahl zurück:
    return 5
}

func main() {
    if zahl := leseZahl(); zahl <= 10 {
        fmt.Println("Die Zahl ist kleiner als oder gleich 10")
    } else {
        fmt.Println("Die Zahl ist größer als 10")
    }
    // an dieser Stelle kann man nicht mehr auf die Variable
    // 'zahl' zugreifen
}

Hier wird vor der Abfrage zahl <= 10 noch eine Zuweisung ausgeführt. Das ist dann interessant, wenn der Wert aus der Funktion leseZahl() nur in der Fallunterscheidung benötigt wird, da die Variable zahl nach der Fallunterscheidung nicht mehr definiert ist. Alternativ würde man folgendes schreiben:

zahl := leseZahl()
if zahl <= 10 {
    fmt.Println("Die Zahl ist kleiner als oder gleich 10")
} else {
    fmt.Println("Die Zahl ist größer als 10")
}
// hier ist die Variable 'zahl' noch bekannt

Damit ist die Variable zahl im weiteren Programmlauf noch sichtbar, denn sie wurde auf äußerster Ebene deklariert.