Tyto tři klíčová slova řeší odloženou exekuci a výjimečné situace. defer naplánuje čištění, panic spustí chybu za běhu (pro skutečně výjimečné případy) a recover může zachytit paniku, aby se zabránilo pádu programu.
Tyto tři klíčová slova řeší odloženou exekuci a výjimečné situace. defer naplánuje čištění, panic spustí chybu za běhu (pro skutečně výjimečné případy) a recover může zachytit paniku, aby se zabránilo pádu programu.
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 naplánuje volání funkce k provedení, když se okolní funkce vrátí — bez ohledu na to, jak se vrátí (normální vrácení, chyba nebo panika). Je to idiomatický způsob, jak zajistit čištění: zavírání souborů, odemykání mutexů, zavírání připojení — umístěné hned vedle získání prostředku, aby ses nemohl zapomenout.
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 zastaví normální tok a rozvinuje zásobník volání (přitom spouštějíc odložené funkce), což nakonec způsobí pád programu. Je to pro chyby programátora / nezvratné podmínky (přístup mimo meze, nil dereference, nemožné stavy) — NIKOLI pro běžné chyby (ty se vrací jako hodnoty 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 znovu získá kontrolu nad goroutinou v panice — ale funguje pouze uvnitř odložené funkce. Používá se zřídka, například aby se zabránilo pádu jediného handleru požadavku v celém serveru.
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 základní, idiomatická vlastnost Go pro zaručené čištění — umístění uvolnění prostředku hned vedle jeho získání a zajištění, že se spustí na každé cestě návratu (včetně panik), což zabráňuje úniku souborů, zámků a připojení mnohem spolehlivěji než ruční čištění.
Pochopení jeho pořadí LIFO je také důležité. panic/recover poskytují mechanismus podobný výjimkám, ale kritický princip je, že Go je vyhrazuje pro skutečně výjimečné, nezvratné situace — běžné chyby by se měly vždy vracet jako hodnoty a kontrolovat.
Zneužití panic/recover jako obecného zpracování výjimek není idiomatické a je to běžná chyba vývojářů, kteří přicházejí z jazyků založených na výjimkách.
Vědění, kdy použít defer (vždy, pro čištění), error návraty (běžné selhání) a panic/recover (vzácně, výjimečně nebo na hranicích) je základem pro psaní správného, idiomatického Go a je to časté téma v pohovorech.