Anonyme Funktionen in Golang

GolangBeginner
Jetzt üben

Einführung

In den vorherigen Labs haben Sie gelernt, wie Sie benannte Funktionen schreiben und verwenden, wie Sie Code in Module organisieren und wie Sie die Lesbarkeit des Codes verbessern, indem Sie die Logik in separate Funktionen aufteilen. In diesem Lab werden wir anonyme Funktionen erkunden, eine spezielle Art von Funktion, die keinen Namen hat. Anonyme Funktionen sind nützlich, wenn Sie ein kleines Stück Logik "vor Ort" definieren möchten, ohne eine separate, benannte Funktion deklarieren zu müssen. Sie sind besonders hilfreich für kurze, eigenständige Operationen oder wenn Sie eine Funktion als Argument an eine andere Funktion übergeben müssen (wie in Callbacks). Durch die Verwendung von anonymen Funktionen können Sie kompakteren und ausdrucksstärkeren Code schreiben.

Wichtige Themen:

  • Was anonyme Funktionen sind und wie Sie sie definieren
  • Warum und wann Sie anonyme Funktionen verwenden sollten
  • Das Aufrufen von anonymen Funktionen ohne sie einem Namen zuzuweisen
  • Das Übergeben von Parametern an anonyme Funktionen und das Rückgeben von Werten
  • Die Verwendung von anonymen Funktionen als Callback-Funktionen für flexibleren Code

Grundlagen der anonymen Funktionen verstehen

Eine anonyme Funktion in Go wird genauso definiert wie eine normale Funktion, mit der Ausnahme, dass sie keinen Namen hat. Stattdessen können Sie sie einer Variablen zuweisen, als Argument übergeben oder sie direkt nach ihrer Definition ausführen. Dies macht sie gut geeignet für kurze, einmalige Operationen oder für das Übergeben von Funktionen als Argumente an andere Funktionen. Anonyme Funktionen sind besonders nützlich, wenn eine Funktion nur einmal benötigt wird und keine separate benannte Funktion rechtfertigt. Sie können dazu beitragen, dass Ihr Code lesbarer wird, indem Sie die Logik in der Nähe ihrer Verwendung halten.

Syntax für eine anonyme Funktion:

func(input parameters)(return parameters) {
    // code block
}

Dies sieht ähnlich aus wie die Definition einer regulären Funktion, aber ohne den Funktionsnamen.

Im Vergleich zu einer regulären Funktionsdeklaration:

// Regular function declaration
func functionName(parameters...)(return values...) {
    code block
}

Warum sollten Sie anonyme Funktionen verwenden?

  • Kompaktheit: Sie ermöglichen es Ihnen, kleine Logikstücke zu definieren, ohne eine separate benannte Funktion erstellen zu müssen, wodurch der Code kompakter wird.
  • Lokaler Gültigkeitsbereich: Der Gültigkeitsbereich von anonymen Funktionen liegt innerhalb der umgebenden Funktion, wodurch die Verschmutzung des Namensraums eingeschränkt wird.
  • Flexibilität: Sie können als Argumente an andere Funktionen übergeben oder direkt definiert und ausgeführt werden.

Wann sollten Sie anonyme Funktionen verwenden?

  • Wenn Sie eine kurze Funktion benötigen, die nirgendwo sonst wiederverwendet wird.
  • Als Callback-Funktionen (dazu werden wir später noch sehen).
  • Wenn Sie eine Funktion sofort ausführen möchten (häufig für die Initialisierung).

Erstellen einer anonymen Funktion ohne Parameter

Beginnen wir mit einem einfachen Beispiel, das "hello world" mithilfe einer anonymen Funktion ausgibt. Zunächst erstellen Sie eine Datei namens anonymous.go im Projektverzeichnis:

cd ~/project
touch anonymous.go

Öffnen Sie anonymous.go und fügen Sie den folgenden Code hinzu:

package main

import "fmt"

func main() {
    // Define an anonymous function and assign it to a variable f
    f := func() {
        fmt.Println("hello world")
    }

    // Call the anonymous function via the variable f
    f()
}

Führen Sie das Programm aus:

go run anonymous.go

Erwartete Ausgabe:

hello world

Hier haben wir eine anonyme Funktion mit der Syntax func() {... } definiert. Diese Funktion nimmt keine Parameter entgegen und gibt keine Werte zurück. Wir haben diese anonyme Funktion der Variablen f zugewiesen. Dann rufen wir die Funktion mit f() auf. Dadurch wird die anonyme Funktion ausgeführt und "hello world" ausgegeben.

Verwendung von Parametern in anonymen Funktionen

Anonyme Funktionen können genau wie reguläre Funktionen Parameter akzeptieren. Ändern wir unseren Code, um einen String als Parameter zu übergeben.

Ersetzen Sie den Inhalt von anonymous.go durch:

package main

import "fmt"

func main() {
    f := func(s string) {
        fmt.Println(s)
    }
    f("hello world")
}

Führen Sie das Programm aus:

go run anonymous.go

Erwartete Ausgabe:

hello world

Diesmal nimmt unsere anonyme Funktion einen String-Parameter s entgegen. Der Teil func(s string) definiert, dass die anonyme Funktion einen Parameter namens s vom Typ String nimmt. Wenn wir f("hello world") aufrufen, wird der String "hello world" an die Funktion übergeben, die ihn dann auf der Konsole ausgibt. Dies zeigt, wie Sie Werte an anonyme Funktionen übergeben können, um sie vielseitiger zu machen.

Rückgabe von Werten aus anonymen Funktionen

Anonyme Funktionen können auch Werte zurückgeben. Erstellen wir eine anonyme Funktion, die zwei Ganzzahlen als Parameter nimmt und ihre Summe zurückgibt.

Ersetzen Sie den Inhalt von anonymous.go durch:

package main

import "fmt"

func main() {
    f := func(a, b int) int {
        return a + b
    }
    result := f(3, 5)
    fmt.Println(result)
}

Führen Sie das Programm aus:

go run anonymous.go

Erwartete Ausgabe:

8

Jetzt lautet die Signatur der anonymen Funktion func(a, b int) int. Das bedeutet, dass sie zwei Ganzzahlen (a und b) als Eingabe nimmt und eine Ganzzahl als Ausgabe zurückgibt. Der Funktionskörper return a + b berechnet und gibt ihre Summe zurück. Wenn wir f(3, 5) aufrufen, wird die anonyme Funktion mit den Argumenten 3 und 5 ausgeführt, und das Ergebnis 8 wird zurückgegeben. Wir speichern dieses Ergebnis dann in der Variablen result und geben es auf der Konsole aus.

Deklarieren und Sofortiges Aufrufen von Anonymen Funktionen

Sie können eine anonyme Funktion direkt definieren und aufrufen, ohne sie einer Variablen zuzuweisen. Dies kann für schnelle, einmalige Operationen nützlich sein.

Aktualisieren Sie anonymous.go:

package main

import "fmt"

func main() {
    res := func(a, b int) int {
        return a + b
    }(3, 5) // Call the anonymous function directly here
    fmt.Println(res)
}

Führen Sie das Programm aus:

go run anonymous.go

Erwartete Ausgabe:

8

Hier haben wir die anonyme Funktion func(a, b int) int { return a + b } definiert und sie sofort aufgerufen, indem wir (3, 5) nach der Funktionsdeklaration hinzugefügt haben. Diese Syntax func(...) {...}(...) ermöglicht es Ihnen, eine Funktion in einem einzigen Ausdruck zu definieren und aufzurufen. Die Argumente in den Klammern werden sofort an die Funktion übergeben. In diesem Fall gibt sie die Summe von 3 und 5 zurück, die dann der Variablen res zugewiesen wird. Dies ist eine gängige Praxis für einfache, sofort ausgeführte Funktionen und nützlich für Initialisierungen oder kurze Berechnungen.

Verwendung von anonymen Funktionen als Callback-Funktionen

Anonyme Funktionen können auch als Callbacks verwendet werden, was bedeutet, dass wir sie als Argumente an andere Funktionen übergeben können. Dies ist nützlich, wenn Sie das Verhalten einer Funktion anpassen möchten, ohne eine benannte Funktion zu erstellen.

Was sind Callback-Funktionen?

Eine Callback-Funktion ist eine Funktion, die als Argument an eine andere Funktion übergeben wird und nach Abschluss der Aufgabe der ersten Funktion ausgeführt wird. Dies ermöglicht es dem Aufrufer, das Verhalten der aufgerufenen Funktion anzupassen, was mehr Flexibilität und Modularität bietet. Im Wesentlichen ruft die Funktion, die einen Callback erhält, die Callback-Funktion zu einem bestimmten Zeitpunkt "zurück".

Warum sollten anonyme Funktionen als Callbacks verwendet werden?

Anonyme Funktionen eignen sich ausgezeichnet als Callback-Funktionen, da sie oft kurze, spezifische Verhaltensweisen darstellen, die nur innerhalb eines bestimmten Kontexts verwendet werden. Die Verwendung einer anonymen Funktion als Callback hält den Code kompakter und vermeidet die Notwendigkeit, eine separate benannte Funktion zu definieren.

Ersetzen Sie anonymous.go durch den folgenden Code:

package main

import (
    "fmt"
    "math"
)

// 'visit' takes a slice and a function. It applies the function to each element in the slice.
func visit(lst []float64, f func(float64)) {
    for _, value := range lst {
        f(value)
    }
}

func main() {
    arr := []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}

    // Use an anonymous function to sum each element with itself
    visit(arr, func(v float64) {
        fmt.Printf("Sum:%.0f ", v+v)
    })
    fmt.Println()

    // Use an anonymous function to multiply each element by itself
    visit(arr, func(v float64) {
        fmt.Printf("Product:%.0f ", v*v)
    })
    fmt.Println()

    // Use an anonymous function to square each element using math.Pow
    visit(arr, func(v float64) {
        v = math.Pow(v, 2)
        fmt.Printf("Square:%.0f ", v)
    })
    fmt.Println()
}

Führen Sie das Programm aus:

go run anonymous.go

Erwartete Ausgabe:

Sum:2 Sum:4 Sum:6 Sum:8 Sum:10 Sum:12 Sum:14 Sum:16 Sum:18
Product:1 Product:4 Product:9 Product:16 Product:25 Product:36 Product:49 Product:64 Product:81
Square:1 Square:4 Square:9 Square:16 Square:25 Square:36 Square:49 Square:64 Square:81

In diesem Programm erstellen wir zunächst eine visit-Funktion, die ein Slice (lst) von float64 und eine Funktion (f) vom Typ func(float64) nimmt. Die visit-Funktion iteriert über das Slice und ruft für jedes Element die bereitgestellte Funktion f auf. Dieses Entwurfsmuster ermöglicht es der visit-Funktion, je nach der bereitgestellten Callback-Funktion f unterschiedliche Logik auszuführen.

Innerhalb der main-Funktion rufen wir visit dreimal mit verschiedenen anonymen Funktionen auf, um zu zeigen, wie Callbacks Flexibilität bieten.

  • Die erste anonyme Funktion berechnet die Summe jedes Elements mit sich selbst.
  • Die zweite anonyme Funktion berechnet das Produkt jedes Elements mit sich selbst.
  • Die dritte anonyme Funktion quadriert jedes Element mit math.Pow.

Dies zeigt, wie eine anonyme Funktion als Callback übergeben werden kann und wie die visit-Funktion unterschiedliche Aktionen basierend auf der als Parameter übergebenen Callback-Funktion ausführen kann. Dies macht Ihren Code wiederverwendbarer und modularer.

Zusammenfassung

In diesem Lab haben Sie sich mit anonymen Funktionen in Go vertraut gemacht. Anonyme Funktionen haben keinen Namen und werden oft für kurze, einmalige Logikabschnitte verwendet. Sie können:

  • Variablen zugewiesen und später aufgerufen werden.
  • Parameter entgegennehmen und Werte zurückgeben.
  • direkt definiert und aufgerufen werden.
  • als Callbacks dienen, wenn sie als Argumente an andere Funktionen übergeben werden, was ein hochgradig flexibles und anpassbares Verhalten ermöglicht.

Anonyme Funktionen bieten Ihnen Flexibilität und Komfort, insbesondere wenn Sie "vor Ort" benutzerdefinierte Logik benötigen, ohne Ihren Code mit zu vielen benannten Funktionen zu überladen. Durch ihre effektive Verwendung können Sie Go-Programme erstellen, die ausdrucksstärker, kompakter und modularer sind. Sie sind ein leistungsstarkes Werkzeug für die Erstellung von sauberem, leserlichem und flexiblerem Code.