Direkt zum Hauptinhalt springen
eLearner.app
Modul 3 · Lektion 4 von 514/50 im Kurs~12 min
Lektionen des Moduls (4/5)

Closures und Funktionen als Werte

In Go sind Funktionen erstklassige Werte: Sie können ihnen zugewiesen werden Variablen, die an andere Funktionen übergeben und zurückgegeben werden. Ein Abschluss ist ein Funktionsliteral (anonym), das die Variablen des erfasst Umgebung, in der es definiert ist.

Funktionsliteral

Eine Funktion ohne Namen, inline geschrieben. Du rufst es sofort an bzw weisen Sie es zu:

Go
greet := func(name string) {
    fmt.Println("ciao", name)
}
greet("Anna")

// invocata immediatamente:
func() { fmt.Println("subito") }()

Der Typ von greet ist func(string).

Die Umgebung erfassen: Schließung

Das Funktionsliteral kann die in sichtbaren Variablen lesen und ändern sein lexikalischer Geltungsbereich, auch nachdem die äußere Funktion zurückgegeben wurde:

Go
func counter() func() int {
    n := 0
    return func() int {
        n++
        return n
    }
}

c := counter()
fmt.Println(c(), c(), c())  // 1 2 3

n „lebt“, solange mindestens ein Abschluss darauf verweist. Jeder Anruf an counter() erstellt einen neuen, unabhängigen n.

Abschluss als Rückruf

Ein sehr häufiges Muster:

Go
nums := []int{3, 1, 2}
sort.Slice(nums, func(i, j int) bool {
    return nums[i] < nums[j]
})

Der Abschluss erfasst nums und definiert die Reihenfolge.

Fungiert als Parameter

Um eine Funktion als Parameter zu akzeptieren, schreiben Sie ihren Typ aus:

Go
func apply(nums []int, f func(int) int) []int {
    out := make([]int, len(nums))
    for i, n := range nums {
        out[i] = f(n)
    }
    return out
}

double := func(x int) int { return x * 2 }
apply([]int{1, 2, 3}, double)   // [2 4 6]

Wenn die Signatur schwer lesbar wird, definieren Sie einen Typalias:

Go
type Transform func(int) int
func apply(nums []int, f Transform) []int { ... }

Probieren Sie es aus

Übung#go.m3.l4.e1
Versuche: 0Wird geladen…

Definieren Sie counter(), das einen Abschluss zurückgibt: Jeder Aufruf des Abschlusses erhöht und gibt einen internen Zähler zurück.

Editor wird geladen…
Hinweis anzeigen

`n` muss VOR der Rückgabe deklariert werden; der Verschluss fängt es ein.

Lösung nach 3 Versuchen verfügbar

Übung#go.m3.l4.e2
Versuche: 0Wird geladen…

Weisen Sie f ein Funktionsliteral zu, das „ciao“ ausgibt, und rufen Sie es dann auf.

Editor wird geladen…
Hinweis anzeigen

Syntax: `f := func() { ... }`, dann `f()`.

Lösung nach 3 Versuchen verfügbar

Quiz#go.m3.l4.e3
Bereit

Was wird hier gedruckt? (Achten Sie auf den Schließungsbereich)

Go
mk := func() func() int {
    x := 0
    return func() int { x++; return x }
}
a := mk()
b := mk()
fmt.Println(a(), a(), b())
Antwortoptionen

Zusammenfassung

  • Funktionen sind erstklassig: zuweisbar, passierbar, rückzahlbar.
  • Funktionsliteral: func(params) ret { ... }, anonym.
  • Abschluss: Erfasst die Variablen des lexikalischen Bereichs und hält sie am Leben.
  • Expliziter Funktionstyp in Parametern: func(int) int.
  • Seit Go 1.22 hat jede for-Iteration eine eigene Kopie der Schleifenvariablen.