Geschiedenis van de vraag:
De operators defer, panic en recover zijn belangrijke mechanismen voor het beheren van de uitvoeringsstroom in Go. De operator defer wordt gebruikt voor het uitstellen van de uitvoering van functies, panic initieert een fout (noodstop), en recover maakt het mogelijk om de noodstop op te vangen en de uitvoering voort te zetten.
Probleem:
Zonder het juiste gebruik van deze hulpmiddelen is het moeilijk om bronnen correct te finaliseren en fouttolerantie te implementeren. Onvoorspelbare beëindiging van functie-uitvoering, niet-vrijgegeven bronnen en ongecontroleerde "afsluiting" van de applicatie bij fouten zijn veelvoorkomende problemen bij een verkeerde aanpak.
Oplossing:
Juist gebruik van defer zorgt voor veilige vrijgave van middelen, zelfs in het geval van fouten. panic is een mechanisme voor noodstop bij ongebruikelijke situaties, dat alleen gebruikt moet worden voor werkelijk uitzonderlijke gevallen. recover biedt de mogelijkheid om de uitvoering te "redden" binnen een uitgestelde functie.
Voorbeeldcode:
func riskyFunction() { defer func() { if r := recover(); r != nil { fmt.Println("Hersteld in riskyFunction:", r) } }() fmt.Println("Wat werk doen...") panic("er gebeurde iets slechts!") } func main() { riskyFunction() fmt.Println("Na riskyFunction") }
Belangrijke kenmerken:
defer wordt altijd in omgekeerde volgorde aangeroepen vóór het verlaten van de functie. Zelfs bij panic.recover werkt ALLEEN binnen uitgestelde functies.panic onderbreekt de uitvoering van de huidige goroutine; als het niet wordt opgevangen via recover, beëindigt het het proces.Waarom werkt recover niet buiten defer binnen dezelfde functie waarin panic plaatsvond?
recover retourneert een niet-nulwaarde (dus vangt de paniek op) alleen als het wordt aangeroepen vanuit een defer-functie, genest in dezelfde functie waarin de panic plaatsvond. Als recover direct wordt aangeroepen, retourneert het altijd nil.
Voorbeeldcode:
func f() { panic("fail!") r := recover() // werkt niet! }
Kan defer na panic worden aangeroepen en zal het worden uitgevoerd?
Nee. Na panic worden alle geregistreerde defer-aanroepen uitgevoerd, maar nieuwe defer na panic worden niet aangeroepen, omdat de uitvoering van de functie al "in elkaar zakt".
Is het mogelijk om te herstellen (recover) van een panic die in een andere goroutine plaatsvond?
Nee, recover werkt alleen voor paniek in de huidige goroutine. Als een andere goroutine panikeert en de aanroep van recover niet in diezelfde goroutine plaatsvond, zal de applicatie beëindigen.
In het project werden alle fouten door panic gegooid, en de recovery-afhandeling was alleen in de hoofdfunctie. Dit leidde ertoe dat bronnen niet werden gesloten, een deel van de gegevens verloren ging en de logboeken onleesbaar waren.
Voordelen:
Nadelen:
In elk kritiek stuk werd defer gebruikt voor het vrijgeven van middelen, panic werd alleen toegepast voor werkelijk uitzonderlijke situaties, en recover werd gebruikt voor isolatie van noodsituaties in niet-kritieke delen. Daarbij werden alle foutdetails gelogd.
Voordelen:
Nadelen: