Ti tri ključne besede upravljajo odloženo izvajanje in izjemne situacije. defer razporedi čiščenje, panic sproži zrušitev ob izvajanju (za res izjemne primere), in recover lahko ujame panik in prepreči padec programa.
Ti tri ključne besede upravljajo odloženo izvajanje in izjemne situacije. defer razporedi čiščenje, panic sproži zrušitev ob izvajanju (za res izjemne primere), in recover lahko ujame panik in prepreči padec programa.
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 razporedi funkcijski klic za izvedbo, ko se obdajoča funkcija vrne — ne glede na način vrnitve (navadna vrnitev, napaka ali panik). To je idiomatični način, kako zagotoviti čiščenje: zapiranje datotek, odklepanje muteksov, zapiranje povezav — postavljeno tik ob pridobitvi, da ne morete pozabiti.
defer fmt.Println("1")
defer fmt.Println("2")
defer fmt.Println("3")
// prints: 3, 2, 1 — last deferred, first executed (stack order)
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 ustavi navaden tok in odvije sklad klicev (pri čemer se izvršijo odložene funkcije), kar na koncu vodi do padca programa. To je za napake programerja / nepopravljive pogoje (presežek meja, dereferenciranje nila, nemogoča stanja) — NE za navadne napake (te se vrnejo kot vrednosti error).
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 ponovno prevzame nadzor nad rutino, ki je v paniki — vendar deluje le znotraj odložene funkcije. Uporabljeno je redko, npr. da se prepriči, da ne zruši celotnega strežnika, ker se porušil en sam rokovnik zahtevka.
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)
defer je bistvena, idiomatična Go lastnost za zagotovljeno čiščenje — postavljanje sprostitve virov tik ob pridobitvi in zagotavljanje, da se izvedeta na vseh poteh povratka (vključno s panikami), kar prepreči puščanje datotek, zakljepanosti in povezav mnogo bolj zanesljivo kot ročno čiščenje.
Razumevanje njegovega LIFO vrstnega reda je tudi pomembno. panic/recover nudita mehanizem, podoben izjemam, vendar je ključno načelo, da Go rezervira ta mehanizma za res izjemne, nepopravljive situacije — navadne napake je treba vedno vrniti kot vrednosti in preveriti.
Zloraba panika/recover kot splošnega upravljanja izjem je neidiomatična in pogosta napaka razvijalcev, ki prihajajo iz jezikov, temeljenih na izjemah.
Znanje, kdaj uporabiti defer (vedno, za čiščenje), vrnitve error (navadne napake) in panic/recover (redko, izjemno ali na mejah) je temeljno za pisanje pravilnega, idiomatičnega Go-ja in pogosta tema na razgovorih za zaposlitev.