Pular para o conteúdo principal
eLearner.app
Módulo 3 · Lição 4 de 514/50 no curso~12 min
Lições do módulo (4/5)

Fechamentos e funções como valores

In Go, functions are first-class values: they can be assigned to variables, passed to other functions, and returned. A closure is a function literal (anonymous) that captures the variables of the environment in which it is defined.

Function literal

A function with no name, written inline. You call it immediately or assign it:

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

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

The type of greet is func(string).

Capturing the environment: closure

The function literal can read and modify the variables visible in its lexical scope, even after the outer function has returned:

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

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

n "lives" as long as at least one closure references it. Each call to counter() creates a new, independent n.

Closure as callback

A very common pattern:

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

The closure captures nums and defines the ordering.

Functions as parameters

To accept a function as a parameter, write out its type:

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]

If the signature becomes hard to read, define a type alias:

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

Try it

Exercício#go.m3.l4.e1
Tentativas: 0Carregando…

Define counter() that returns a closure: each call to the closure increments and returns an internal counter.

Carregando editor…
Mostrar dica

`n` must be declared BEFORE the return; the closure captures it.

Solução disponível após 3 tentativas

Exercício#go.m3.l4.e2
Tentativas: 0Carregando…

Assign to f a function literal that prints 'ciao', then call it.

Carregando editor…
Mostrar dica

Syntax: `f := func() { ... }` then `f()`.

Solução disponível após 3 tentativas

Quiz#go.m3.l4.e3
Pronto

What does this print? (watch out for closure scope)

Go
mk := func() func() int {
    x := 0
    return func() int { x++; return x }
}
a := mk()
b := mk()
fmt.Println(a(), a(), b())
Opções de resposta

Recap

  • Functions are first-class: assignable, passable, returnable.
  • Function literal: func(params) ret { ... }, anonymous.
  • Closure: captures the variables of the lexical scope, keeps them alive.
  • Explicit function type in parameters: func(int) int.
  • Since Go 1.22, every for iteration has its own copy of the loop variable.