Let’s revisit exception handling in Golang 😸
- 1.Golang is not found in other languages
try... catch...
Statement to catch exceptions and exception recovery - 2. We usually use Golang
panic
Keyword to throw an exception indefer
The use ofrecover
To catch exceptions for specific logical processing - 3. In Golang we usually return in a function or method
error
Structure object to determine if an exception occurs
Matters needing attention
- 1. The use of
recover
andpanic
Instructions,defer
Must be defined before panic (Panic terminates subsequent code execution
). - 2.
recover
Only in thedefer
Is valid only in the function called, otherwiserecover
Uncapturepanic
. - 3.
recover
After handling the exception, the business logic runs todefer
Later in the processing fragment - More than 4.
defer
Will form theDefer the stack
- 5. Panic will wait until the whole
goroutine
An error is reported only when you exit
Routine use of
panic
As well asrecover
Parameter type is empty interface (can store objects of any type)interface{}
/* func panic(v interface{}) func recover() interface{} what can I ask? Panic. Explain: */ package main import (" FMT ") func main() {defer func() {if err := recover(); err ! = nil { fmt.Println(err) } }() panic("oh my god! panic.") }Copy the code
- Errors raised in deferred calls can be caught by subsequent deferred calls (
Only the last error was caught
)
/* Defer anonymous function with panic()-> defer anonymous function with recover() Recover in defer can only catch the last error package main import (" FMT ") func main() {defer func() {if err := recover(); err ! = nil { fmt.Println("catch the panic") } }() defer func() { panic("oh my god! panic.") }() panic("something panic!" )}Copy the code
- Capture function
recover()
Only in thedefer
A direct call within the call terminates, otherwise returnsnil
/* The code is implemented in the following order :panic-> nest the recover defer function in the anonymous function -> FMT defer-> recover defer-> call the recover defer function in the anonymous function: Defer inner <nil> defer recover panic error The third defer printed 'nil' of Recover (), Only the first defer successfully captured the bottom panic("panic error") */ package main import "FMT" func main() {defer func() {fmt.println ("defer recover",recover()) }() defer recover() defer fmt.Println(recover()) defer func() { func(){ fmt.Println("defer inner") recover() }() }() panic("panic error") }Copy the code
- Placing code blocks in anonymous functions enables exception recovery within the function logic without affecting the main function
/* Defer defer defer defer defer defer defer defer defer defer defer defer defer 2 explanation: Panic will terminate subsequent execution, so panic in the anonymous function will be executed first, and recover in defer will be captured, and I will be assigned to 2. */ package main import "FMT" func main() {test()} func test() {var I int func() {var I int func() { defer func(){ if err := recover(); err ! = nil { i = 2 } }() panic("something panic!" ) i += 8 fmt.Println("no panic, i is:",i) }() fmt.Println("i is:",i) }Copy the code
- The recover goroutine
Note: If a panic occurs in a Goroutine that is not recovered, the entire process will die
/ * WaitGroup is used to Wait for the end of a set of goroutines,Add is used to set the number of goroutines to Wait, and Done is used to indicate the end of a goroutine.Wait is used to block all goroutines until all goroutines are executed -> Wg.wait ()-> FMT.Println panic recover Assignment to entry in nil map donw In goroutine we declare a map[string]string of info. We know that map,slice, and channel are all reference types that need to be initialized by make. The assignment directly using info["name"] = "BGBiao" causes panic, and the fmt.println function is terminated, so defer with Recover is executed. Then defer with Wg.done () and exit Goroutine to execute the main program logic */ package main import (" FMT ""sync") func main() {var wg sync.waitgroup wg.Add(4) go func() { defer wg.Done() defer func() { if err := recover(); err ! = nil { fmt.Println("panic recover",err) } }() var info map[string]string info["name"] = "BGBiao" fmt.Println(info) }() wg.Wait() fmt.Println("done") }Copy the code
Welcome to follow my official account: BGBiao, progress together ~