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:
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ı:
func counter() func() int {
n := 0
return func() int {
n++
return n
}
}
c := counter()
fmt.Println(c(), c(), c()) // 1 2 3n 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:
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:
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:
type Transform func(int) int
func apply(nums []int, f Transform) []int { ... }Deneyin
Bir kapatma döndüren counter() tanımlayın: kapatmaya yapılan her çağrı artar ve bir dahili sayaç döndürür.
İpucu göster
'n' dönüşten ÖNCE beyan edilmelidir; kapanış onu yakalar.
3 denemeden sonra çözüm mevcut
f'ye 'ciao' yazdıran bir işlev değişmezi atayın ve onu çağırın.
İpucu göster
Sözdizimi: `f := func() { ... }` sonra `f()`.
3 denemeden sonra çözüm mevcut
Bu ne yazdırıyor? (kapanma kapsamına dikkat edin)
mk := func() func() int {
x := 0
return func() int { x++; return x }
}
a := mk()
b := mk()
fmt.Println(a(), a(), b())Ö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.