Kann man eine Funktion als Parameter übergeben? Ja, und hier ist, warum das alles verändert
\n\nHaben Sie sich jemals gefragt, ob man in Go eine Funktion in eine andere übergeben kann, wie eine normale Variable? Wenn Sie aus der Welt von Python oder JavaScript kommen, ist das für Sie ein vertrautes Pattern. Aber in Go, trotz aller Strenge, Funktionen als Parameter — das ist nicht nur "möglich", es ist eines der mächtigsten Werkzeuge der Sprache.
\n\nIch erinnere mich an meine erste Begegnung mit diesem Konzept: Ich schrieb ein Dienstprogramm zur Logverarbeitung und stellte fest, dass ich dieselbe Schleife mit unterschiedlicher Logik darin kopierte. Die Lösung kam, als ich erkannte, dass ich einfach die benötigte Funktion als Argument übergeben konnte. Der Code wurde sauberer, kürzer und verständlicher. In diesem Artikel zeige ich Ihnen, wie Sie die Übergabe einer Funktion an eine Funktion in Go meistern — von einfachen Beispielen bis zu echten Patterns, die Sie morgen bei der Arbeit verwenden können.
\n\nÜbrigens sehen wir auf PythonLib oft Fragen wie "Can functions be passed as parameters?" auf Stack Overflow mit Tausenden von Aufrufen. Lassen Sie uns dieses Thema ein für alle Mal am Beispiel von Go behandeln.
\n\nWas sind Funktionen als Parameter in Go?
\n\nIn Go sind Funktionen Objekte erster Klasse. Das bedeutet, man kann sie:
\n- \n
- Variablen zuweisen \n
- An andere Funktionen übergeben \n
- Von Funktionen zurückgeben \n
- In Strukturen und Slices speichern \n
Wenn wir über Funktionen als Parameter sprechen, meinen wir, dass eine Funktion eine andere Funktion als Argument annimmt und sie in sich selbst aufruft. Klingt kompliziert? In Wirklichkeit ist es einfacher, als es scheint.
\n\nSyntax: Wie deklariert man eine Funktion, die eine andere Funktion annimmt
\n\nIn Go muss man den Typ der Parameterfunktion explizit angeben. Das sieht so aus:
\n\n// Deklarieren des Funktionstyps\ntype Transformer func(string) string\n\n// Funktion, die eine andere Funktion annimmt\nfunc processText(text string, transform Transformer) string {\n return transform(text)\n}\n\nOder man kann den Typ direkt in der Signatur deklarieren:
\n\nfunc processText(text string, transform func(string) string) string {\n return transform(text)\n}\n\nBeide Varianten sind funktionsfähig. Die erste ist praktischer, wenn Sie den Typ wiederverwenden möchten. Die zweite für schnelle Lösungen.
\n\nEinfaches Beispiel: Eine Begrüßungsfunktion übergeben
\n\nSchreiben wir etwas Lebensnahes. Stellen Sie sich vor, Sie haben eine Funktion, die den Benutzernamen formatiert, und Sie möchten verschiedene Begrüßungen einsetzen:
\n\npackage main\n\nimport "fmt"\n\n// Typ für die Begrüßungsfunktion\ntype Greeter func(name string) string\n\n// Funktion, die eine Begrüßung annimmt\nfunc greetUser(name string, greeter Greeter) {\n message := greeter(name)\n fmt.Println(message)\n}\n\nfunc main() {\n // Normale Begrüßung\n normalGreet := func(name string) string {\n return "Hallo, " + name + "!"\n }\n\n // Formelle Begrüßung\n formalGreet := func(name string) string {\n return "Sehr geehrte(r) " + name + ", guten Tag."\n }\n\n greetUser("Anna", normalGreet)\n greetUser("Anna", formalGreet)\n}\n\nAusgabe:
\nHallo, Anna!\nSehr geehrte(r) Anna, guten Tag.\n\nSehen Sie? Wir haben einfach verschiedene Funktionen an dieselbe greetUser übergeben. Das ist die Übergabe einer Funktion als Argument in Aktion.
Callback-Funktionen: Wenn das Ergebnis verarbeitet werden muss
\n\nEines der häufigsten Szenarien für die Verwendung von Funktionen als Parameter sind Callbacks. Sie führen eine Operation aus und rufen die übergebene Funktion auf, wenn die Operation abgeschlossen ist.
\n\npackage main\n\nimport (\n "fmt"\n "time"\n)\n\n// Funktion, die einen langen Datenladevorgang simuliert\nfunc fetchData(callback func(string)) {\n fmt.Println("Daten werden geladen...")\n time.Sleep(2 * time.Second) // Simulation einer Verzögerung\n data := "Wichtige Daten aus der Datenbank"\n callback(data)