Ketiga keyword ini menangani eksekusi yang ditangguhkan dan situasi luar biasa. defer menjadwalkan pembersihan, panic memicu crash runtime (untuk kasus yang benar-benar luar biasa), dan recover dapat menangkap panic untuk mencegah program crash.
defer — jadwalkan panggilan untuk ketika fungsi kembali
func readFile() error {
f, err := os.Open("file.txt")
if err != nil { return err }
defer f.Close() // GUARANTEED to run when readFile returns (any path)
// ... use f, with multiple return points ...
return nil // f.Close() runs here automatically
}
defer menjadwalkan pemanggilan fungsi untuk dieksekusi ketika fungsi sekitarnya kembali — tidak peduli bagaimana cara kembalinya (return normal, error, atau panic). Ini adalah cara idiomatic untuk memastikan pembersihan: menutup file, membuka kunci mutex, menutup koneksi — ditempatkan tepat di sebelah akuisisi sehingga Anda tidak bisa melupakannya.
Multiple defer berjalan dalam urutan LIFO
defer fmt.Println("1")
defer fmt.Println("2")
defer fmt.Println("3")
// prints: 3, 2, 1 — last deferred, first executed (stack order)
panic — untuk situasi yang benar-benar luar biasa dan tidak dapat dipulihkan
func mustPositive(n int) {
if n < 0 {
panic("negative not allowed") // stops normal execution, unwinds the stack
}
}
// panic runs deferred functions as it unwinds, then crashes the program (with a stack trace)
panic menghentikan aliran normal dan membuka gulungan stack panggilan (menjalankan fungsi yang ditangguhkan), pada akhirnya crash program. Ini untuk kesalahan programmer / kondisi yang tidak dapat dipulihkan (out-of-bounds, nil dereference, keadaan yang mustahil) — BUKAN untuk error biasa (error tersebut menggunakan nilai error yang dikembalikan).
recover — tangkap panic (hanya di dalam fungsi yang ditangguhkan)
func safeProcess() {
defer func() {
if r := recover(); r != nil { // recover() returns the panic value
fmt.Println("recovered from:", r) // handle it; program continues
}
}()
panic("something broke") // this panic is caught by the recover above
}
// safeProcess returns normally instead of crashing
recover mendapatkan kembali kontrol goroutine yang panic — tetapi hanya bekerja di dalam fungsi yang ditangguhkan. Ini digunakan dengan hemat, misalnya untuk menghentikan single handler request dari crash seluruh server.
Prinsip utama: jangan gunakan panic/recover untuk error normal
Normal/expected failures (file missing, bad input, validation) → return an error value
panic/recover → reserve for TRULY exceptional cases (bugs, unrecoverable states)
and boundaries (e.g. a server recovering so one bad request doesn't kill the process)
Mengapa ini penting
defer adalah fitur Go yang essential dan idiomatic untuk pembersihan yang dijamin — menempatkan pelepasan resource tepat di sebelah akuisisi dan memastikan berjalan pada setiap jalur return (termasuk panic), yang mencegah bocor file, lock, dan koneksi jauh lebih dapat diandalkan daripada pembersihan manual.
Memahami urutan LIFO-nya juga penting. panic/recover menyediakan mekanisme seperti exception, tetapi prinsip kritis adalah bahwa Go mereservasi mereka untuk situasi yang benar-benar luar biasa dan tidak dapat dipulihkan — error normal harus selalu dikembalikan sebagai nilai dan diperiksa.
Menyalahgunakan panic/recover sebagai penanganan exception umum tidak idiomatic dan merupakan kesalahan umum bagi developer yang berasal dari bahasa berbasis exception.
Mengetahui kapan menggunakan defer (selalu, untuk pembersihan), return error (kegagalan normal), dan panic/recover (jarang, luar biasa, atau di boundary) adalah fundamental untuk menulis Go yang benar dan idiomatic dan topik interview yang sering.
