Ana içeriğe geç
Modül 3 · Ders 4 ders 5Kurstaki 14/50~12 min
Modül dersleri (4/5)

Değer olarak kapanışlar ve işlevler

Go'da işlevler birinci sınıf değerlerdir: bunlara atanabilirler değişkenler diğer işlevlere aktarılır ve geri döndürülür. kapanış bir değişkenlerini yakalayan değişmez işlev (anonim) tanımlandığı ortamdır.

İşlev değişmezi

Adı olmayan, satır içi yazılmış bir işlev. Hemen ararsınız veya onu atayın:

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

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

greet türü func(string) şeklindedir.

Çevreyi yakalamak: kapanış

Fonksiyon değişmezi, içinde görünen değişkenleri okuyabilir ve değiştirebilir dış işlev geri döndükten sonra bile sözcüksel kapsamı:

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

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

n en az bir kapanış ona referans verdiği sürece "yaşar". Her çağrı counter() yeni, bağımsız bir n oluşturur.

Geri arama olarak kapatma

Çok yaygın bir kalıp:

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

Kapatma nums öğesini yakalar ve sıralamayı tanımlar.

Parametre olarak işlevler

Bir işlevi parametre olarak kabul etmek için türünü yazın:

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]

İmzanın okunması zorlaşıyorsa bir tür takma adı tanımlayın:

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

Deneyin

Egzersiz#go.m3.l4.e1
Denemeler: 0Yükleniyor…

Bir kapatma döndüren counter() tanımlayın: kapatmaya yapılan her çağrı artar ve bir dahili sayaç döndürür.

Düzenleyici yükleniyor…
İpucu göster

'n' dönüşten ÖNCE beyan edilmelidir; kapanış onu yakalar.

3 denemeden sonra çözüm mevcut

Egzersiz#go.m3.l4.e2
Denemeler: 0Yükleniyor…

f'ye 'ciao' yazdıran bir işlev değişmezi atayın ve onu çağırın.

Düzenleyici yükleniyor…
İpucu göster

Sözdizimi: `f := func() { ... }` sonra `f()`.

3 denemeden sonra çözüm mevcut

Quiz#go.m3.l4.e3
Hazır

Bu ne yazdırıyor? (kapanma kapsamına dikkat edin)

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

Özet

  • İşlevler birinci sınıftır: atanabilir, geçirilebilir, geri döndürülebilir.
  • İşlev değişmezi: func(params) ret { ... }, anonim.
  • Kapanış: sözcüksel kapsamın değişkenlerini yakalar, onları canlı tutar.
  • Parametrelerde açık işlev türü: func(int) int.
  • Go 1.22'den beri her for yinelemesinde döngü değişkeninin kendi kopyası vardır.