Go: Satu Hal Yang Perlu Diketahui Sebelum Menggunakan Defer

Go: Satu Hal Yang Perlu Diketahui Sebelum Menggunakan Defer

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
Bisa dilihat kalau 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)
    }
Kita akan mendapatkan:
myFunc's myStr:  altered
deferedFunc's str:  altered

Menurut saya hal ini penting untuk diketahui untuk menghindari bugs yang tidak terduga ketika menggunakan defer.

go 

See also

comments powered by Disqus