Blog

Kata - Funktionen gehen

Dennis Vriend

Aktualisiert Oktober 21, 2025
3 Minuten

Manchmal müssen Sie Dinge immer und immer wieder tun, um die Konzepte und die Theorie wirklich zu verinnerlichen. Das Gleiche gilt für Programmiersprachen. Nehmen Sie zum Beispiel eine Go-Funktion. Wenn Sie wie ich in verschiedenen Sprachen programmieren, ist es wirklich wichtig, die Sprache zu sprechen". In diesem Blog werden wir lernen, wie man Go-Funktionen auf idiomatische Weise strukturiert.

Eine einfache Funktion

Untersuchen wir die folgende Funktion, die einen S3-Client für eine bestimmte Region erstellt und ein Tupel aus S3-Client und einem Fehler zurückgibt. Go-Funktionen geben Fehler früh zurück und geben Werte spät zurück. Einen Fehler früh zurückgeben bedeutet, dass ein Fehler zurückgegeben wird, wenn ein Problem auftritt. Einen Wert spät zurückgeben bedeutet, dass am Ende der Funktion ein Wert zurückgegeben werden soll. Der Inhalt des Tupels kann variieren, je nachdem, wann die Funktion zurückgekehrt ist. Wenn ein Fehler auftritt, ist der Wert nil und der Fehler hat einen Wert. Wenn kein Problem auftritt, ist error gleich null und hat einen Wert.
Der Go-Stil beim Erstellen von Funktionen bedeutet, dass Fehler immer zuerst überprüft werden sollten. Wenn die Fehler ordnungsgemäß behoben wurden, bleibt nur noch die Arbeit mit dem Wert.

func CreateS3Client(region string) (*s3.S3, error) {
    sess, err := session.NewSession()
    if err != nil {
        return nil, err
    }
    svc := s3.New(sess, aws.NewConfig().WithRegion(region))
    return svc, nil
}

Der folgende Ausschnitt stammt zum Beispiel von io/ioutil und zeigt die gleiche Art der Codierung einer Funktion.

func ReadFile(filename string) ([]byte, error) {
    f, err := os.Open(filename)
    if err != nil {
        return nil, err
    }
    defer f.Close()
    var n int64 = bytes.MinRead
    if fi, err := f.Stat(); err == nil {
        if size := fi.Size() + bytes.MinRead; size > n {
            n = size
        }
    }
    return readAll(f, n)
}

Sichtlinie

Der Go-Stil der Fehlerbehandlung in einem if-Block bedeutet, dass der Code so strukturiert ist, dass die Fehlerbehandlung von der Wertebehandlung eingerückt ist. Der Effekt dieses Stils wird Line-of-Sight genannt und ist in der Abbildung unten dargestellt. Die grüne Linie zeigt, dass die Wertebehandlung an der grünen Linie liegt und die rote Linie ist die Fehlerbehandlung. Wenn Sie sich Go-Codebases ansehen, können Sie den Code leicht anhand der Einrückung scannen.
Sichtverbindung
Umgang mit Fehlern


Die main-Funktion ist anders. In main prüfen wir immer noch zuerst auf Fehler, aber anstatt Fehler zurückzugeben, behandeln wir Fehler frühzeitig. Jedes Mal, wenn wir eine Funktion aufrufen, die ein Wert/Fehler-Paar zurückgibt, müssen wir den Fehler behandeln. Das Ergebnis ist derselbe Stil der Fehlerbehandlung mit Einrückung und Übergabe von Werten auf der linken Seite der Funktion.

func main() {
    svc, err := CreateS3Client("eu-west-1")
    if err != nil {
        log.Fatal(err)
    }
    buckets, err := ListBuckets(svc)
    if err != nil {
        log.Fatal(err)
    }
    RenderBuckets(buckets)
}

Schlussfolgerungen

Das Schreiben idiomatischer Go-Funktionen besteht darin, Fehler früh und Werte spät zurückzugeben. In der Hauptfunktion behandeln wir Fehler immer dann, wenn wir ein Wert/Fehler-Paar erhalten. Der Go-Stil, Funktionen zu spezifizieren, führt zu einer Sichtlinie, bei der wir uns leicht darauf konzentrieren können, wo Fehler behandelt werden, nämlich auf die eingerückten Blöcke. Der Hauptfluss der Berechnungen mit Werten befindet sich immer auf der linken Seite des Codeblocks. Go-Code ist von Natur aus sehr imperativ und das ist auch gut so, denn es führt zu verständlichem Code. Zeit für ein paar weitere Katas!


Tags:

Verfasst von

Dennis Vriend

Contact

Let’s discuss how we can support your journey.