Open 499689317 opened 4 years ago
defer后接一条函数执行语句,当defer所在的函数中执行了return语句,运行到函数结束或当前goroutine panic时会执行defer函数,通常用于资源释放,日志打印,异常捕获等场景。
多个defer语句一起声明时,按栈顺序先进后出顺序执行。
defer函数有可能会改变当前外层函数的返回值。
如果defer语句前的代码panic了,则panic后的defer语句将无法执行到。
调用test1函数时,test2函数内发生panic则会被test2内的recover捕获,如果test2的defer函数没有recover,则会将panic向上抛出在test1的defer函数中recover,如果test1的defer函数也没有recover则继续向当抛出直到被recover,如果一直没有recover则抛出的panic到当前goroutine最上层函数,程序直接异常终止。
func test1() { defer func() { fmt.Println("test1 defer") }() test2() } func test2() { defer func() { if err := recover(); err != nil { fmt.Println("test2 defer recover") } }() panic("test2") }
Go语言defer语句注意事项
defer后接一条函数执行语句,当defer所在的函数中执行了return语句,运行到函数结束或当前goroutine panic时会执行defer函数,通常用于资源释放,日志打印,异常捕获等场景。
多个defer语句一起声明时,按栈顺序先进后出顺序执行。
defer函数有可能会改变当前外层函数的返回值。
如果defer语句前的代码panic了,则panic后的defer语句将无法执行到。
调用test1函数时,test2函数内发生panic则会被test2内的recover捕获,如果test2的defer函数没有recover,则会将panic向上抛出在test1的defer函数中recover,如果test1的defer函数也没有recover则继续向当抛出直到被recover,如果一直没有recover则抛出的panic到当前goroutine最上层函数,程序直接异常终止。