Defer adalah salah satu yang menjadi favorit saya di Go. Kita dapat menggunakannya untuk menjalankan suatu operasi sebelum function return. Suatu hal yang sangat berguna. Sepertinya hampir semua programmer Go pernah menggunakan defer
di aplikasinya. Tapi ada satu hal yang harus diketahui sebelum menggunakan defer di Go.
Jadi apa yang perlu diketahui sebelum menggunakan defer? Yaitu parameter fungsi yang dijalankan defer langsung dievaluasi walaupun fungsinya dieksekusi sebelum fungsi di luarnya return. Ini tertulis di dalam specification dan di Tour of Go, tapi sepertinya banyak orang yang awalnya belum mengetahui ini (termasuk saya haha). Jadi apa ini artinya? Let’s see it in action.
Saya menggunakan code ini untuk mengujinya:
func myFunc() {
myStr := "intial"
defer deferedFunc(myStr)
myStr = "altered"
fmt.Println("myFunc's myStr: ", myStr)
}
func deferedFunc(str string) {
fmt.Println("deferedFunc's str: ", str)
}
Jadi ada dua fungsi, myFunc
dan deferedFunc
. Fungsi myFunc
men-declare dan inisiasi sebuah variabel string, lalu menggunakan defer dengan string tersebut sebagai parameter untuk fungsi deferedFunc
, kemudian value dari string tersebut diubah dan di print. Fungsi deferedFunc
juga akan mem-print variable yang diterima.
Run code tersebut dan kita akan mendapatkan ini di terminal:
myFunc's myStr: altered
deferedFunc's str: intial
fmt.Println
di dalam deferedFunc
dieksekusi terakhir, tapi dia mendapatkan nilai string yang awal sebagai parameternya. Nilai string diubah sebelum function defer dipanggil, tetapi fungsi yang di defer mendapatkan nilai string awal karena parameter tersebut langsung dievaluasi ketika defer dibuat.Jadi bagaimana kalai kita ingin menggunakan nilai yang terbaru pada fungsi deferedFunc
? Untuk melakukan ini, kita dapat menggunakan anonymous function yang memanggil deferedFunc
.
func myFunc() {
myStr := "intial"
defer func() {
deferedFunc(myStr)
}()
myStr = "altered"
fmt.Println("myFunc's myStr: ", myStr)
}
func deferedFunc(str string) {
fmt.Println("deferedFunc's str: ", str)
}
myFunc's myStr: altered
deferedFunc's str: altered
Menurut saya hal ini penting untuk diketahui untuk menghindari bugs yang tidak terduga ketika menggunakan defer.