Direct naar de hoofdinhoud
Module 3 · Les 4 van 514/50 in de cursus~12 min
Modulelessen (4/5)

Afsluitingen en functies als waarden

In Go zijn functies eersteklaswaarden: ze kunnen worden toegewezen variabelen, doorgegeven aan andere functies en geretourneerd. Een sluiting is een functie letterlijk (anoniem) die de variabelen vastlegt van de omgeving waarin het wordt gedefinieerd.

Functie letterlijk

Een functie zonder naam, inline geschreven. Je noemt het meteen of wijs het toe:

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

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

Het type greet is func(string).

Het vastleggen van de omgeving: afsluiting

De functie letterlijk kan de zichtbare variabelen lezen en wijzigen zijn lexicale reikwijdte, zelfs nadat de uiterlijke functie is teruggekeerd:

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

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

n "leeft" zolang minstens één afsluiting ernaar verwijst. Elke oproep naar counter() creëert een nieuwe, onafhankelijke n.

Sluiting als terugbelverzoek

Een veel voorkomend patroon:

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

De afsluiting legt nums vast en definieert de volgorde.

Functioneert als parameters

Om een ​​functie als parameter te accepteren, schrijft u het type ervan op:

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]

Als de handtekening moeilijk leesbaar wordt, definieer dan een typealias:

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

Probeer het

Oefening#go.m3.l4.e1
Pogingen: 0Laden…

Definieer counter() die een afsluiting retourneert: elke aanroep naar de afsluiting wordt verhoogd en retourneert een interne teller.

Editor laden…
Toon hint

`n` moet VOOR de terugkeer worden aangegeven; de sluiting vangt het op.

Oplossing beschikbaar na 3 pogingen

Oefening#go.m3.l4.e2
Pogingen: 0Laden…

Wijs aan f een letterlijke functie toe die 'ciao' afdrukt, en roep deze vervolgens aan.

Editor laden…
Toon hint

Syntaxis: `f := func() { ... }` en vervolgens `f()`.

Oplossing beschikbaar na 3 pogingen

Quiz#go.m3.l4.e3
Klaar

Wat drukt dit af? (let op sluitingsbereik)

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

Samenvatten

  • Functies zijn eersteklas: toewijsbaar, redelijk, herbruikbaar.
  • Functie letterlijk: func(params) ret { ... }, anoniem.
  • Sluiting: vangt de variabelen van de lexicale reikwijdte op en houdt ze levend.
  • Expliciet functietype in parameters: func(int) int.
  • Sinds Go 1.22 heeft elke for-iteratie zijn eigen kopie van de lusvariabele.