Golang Anonymous Functions And Closures

2 minute read

Anonymous Functions

Kisaca isimsiz fonksiyon diyebiliriz. Isim verilmemesi haricinde ayni normal fonksiyonlar gibi alacagi parametreler ve donus degerleri belirtilir. Anonim fonksiyonlar degiskenlere atanabilir. Bu degiskene atanmis fonksiyon sonradan degistirilebilir. Ornek verelim;

package main

import "fmt"

var DoStuff func() = func() {
  // Do stuff
}

func main() {
  DoStuff()

  DoStuff = func() {
    fmt.Println("Doing stuff!")
  }
  DoStuff()

  DoStuff = func() {
    fmt.Println("Doing other stuff.")
  }
  DoStuff()
}

Output:

Doing stuff!
Doing other stuff.

Burada belirtmek gerekir ki degiskenlere sadece anonim degil, normal fonksiyonlar da atanabilir. Buna da bir ornek ;

package main

import "fmt"

func RegFunc() { fmt.Println("reg func") }

func main() {
	DoStuff := RegFunc
	DoStuff()
}

Closures

Bu closures dedigimiz sey ozunde yine anonim fonksiyondur fakat kendi govdesinin haricinde deklare edilmis degiskenleri de kullanir. Yani bu fonksiyonlara degiskenleri parametre olarak vermiyoruz da fonksiyonlar kendi iclerinde global variable kullanir gibi degiskenleri kullaniyor diye dusunebiliriz.

package main

import "fmt"

func main() {
  n := 0
  counter := func() int {
    n += 1
    return n
  }
  fmt.Println(counter())
  fmt.Println(counter())
}

Yukaridaki counter fonksiyonu her calistirildiginda n sayisini bir artirarak toplamda kac kez calistirildigini belirten sayiyi donuyor fakat burada sayan-i dikkat bir durum var , n degiskenine closure fonksiyonumuz disindan da mudahale olabilir. Yani alakasiz bir fonksiyon bu n degiskenine erisip 2 kez artirabilir ve carsiyi karistirabilir. Bunun onune gecmek icin bizim bu n degiskenini kodun geri kalanindan izole etmemiz lazim. Onun ornegini de asagiya kopyalayalim;

package main

import "fmt"

func main() {
  counter := newCounter()
  fmt.Println(counter())
  fmt.Println(counter())
}

func newCounter() func() int {
  n := 0
  return func() int {
    n += 1
    return n
  }
}

Yukarida goruldugu uzere n degiskenimiz main icerisinde degil de newCounter fonksiyonu icerisinde olusturulmustur. newCounter fonksiyonu da goruldugu uzere bir anonim fonksiyon donmektedir.

Netice itibariyle biz closurelar sayesinde bir fonksiyonun icerisine sadece o fonksiyona ait yani kodun geri kalanindan izole edilmis degiskenler gomebilmeyi basardik. Bunu standart bir fonksiyonla yapamazdik cunku fonksiyonun icerisinde olusturdugumuz degiskenler, fonksiyonu her calistirdigimizda tekrardan initialize edilecekti. Burada ise anonim fonksiyonumuzu ve kullanmak istedigimiz degiskenleri bir baska fonksiyonun icerisine sarip sarmaladik, geriye anonim fonksiyonu dondurduk. Bu anonim fonksiyonumuz da kodun kalanindan izole edilmis, adeta kendisine hususi tahsis edilmis degiskenlerle oynamanin tadina doydu. Yasiyorsun bu runtime’i anonim fonksiyon…

Pek tabii closure’larin tek kullanim alani veri izolasyonu degil. Kalan kullanisli yanlariyla ilgili fikir sahibi olmak icin asagidaki linke gidebilirsiniz. Ya da beraber gidelim. 3 deyince tikliyoruz OoOoOoO 1 , 2 , 3

Kaynaklar

https://www.geeksforgeeks.org/anonymous-function-in-go-language/ https://www.calhoun.io/what-is-a-closure/ https://www.calhoun.io/5-useful-ways-to-use-closures-in-go/

Leave a comment