Lompati ke konten utama
Modul 3 · Pelajaran 4 dari 514/50 dalam kursus~12 min
Pelajaran modul (4/5)

Penutupan dan berfungsi sebagai nilai

Di Go, fungsi adalah nilai kelas satu: fungsi dapat ditetapkan ke dalamnya variabel, diteruskan ke fungsi lain, dan dikembalikan. Penutupan adalah a fungsi literal (anonim) yang menangkap variabel dari lingkungan di mana ia didefinisikan.

Fungsi literal

Sebuah fungsi tanpa nama, ditulis sebaris. Anda segera meneleponnya atau menugaskannya:

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

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

Jenis greet adalah func(string).

Menangkap lingkungan: penutupan

Fungsi literal dapat membaca dan memodifikasi variabel yang terlihat di dalamnya cakupan leksikalnya, bahkan setelah fungsi luarnya kembali:

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

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

n "hidup" selama setidaknya satu penutupan merujuknya. Setiap panggilan ke counter() membuat n baru dan mandiri.

Penutupan sebagai panggilan balik

Pola yang sangat umum:

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

Penutupan menangkap nums dan menentukan pemesanan.

Berfungsi sebagai parameter

Untuk menerima suatu fungsi sebagai parameter, tuliskan tipenya:

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]

Jika tanda tangan sulit dibaca, tentukan tipe alias:

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

Cobalah

Latihan#go.m3.l4.e1
Upaya: 0Memuat…

Definisikan counter() yang mengembalikan penutupan: setiap panggilan ke penutupan menambah dan mengembalikan penghitung internal.

Memuat editor…
Tunjukkan petunjuk

`n` harus dideklarasikan SEBELUM pengembalian; penutupan menangkapnya.

Solusi tersedia setelah 3 upaya

Latihan#go.m3.l4.e2
Upaya: 0Memuat…

Tetapkan ke f fungsi literal yang mencetak 'ciao', lalu panggil.

Memuat editor…
Tunjukkan petunjuk

Sintaks: `f := func() { ... }` lalu `f()`.

Solusi tersedia setelah 3 upaya

Quiz#go.m3.l4.e3
Siap

Apa yang dicetak ini? (hati-hati terhadap cakupan penutupan)

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

Rekap

  • Fungsinya kelas satu: dapat dialihkan, dapat dilewati, dapat dikembalikan.
  • Fungsi literal: func(params) ret { ... }, anonim.
  • Penutupan: menangkap variabel lingkup leksikal, membuatnya tetap hidup.
  • Tipe fungsi eksplisit dalam parameter: func(int) int.
  • Sejak Go 1.22, setiap iterasi for memiliki salinan variabel loopnya sendiri.