一: panic和recover
作用:panic 用来主动抛出错误; recover 用来捕获 panic 抛出的错误。
概述: 1,引发panic有两种情况 1)程序主动调用panic函数 2)程序产生运行时错误,由运行时检测并抛出 过程: ! 发生 panic 后,程序会从调用 panic的函数位置或发生panic 的地方立即返回,逐层向上执行函数的defer语句, 然后逐层打印函数调用堆栈,直到被 recover 捕获或运行到最外层函数而退出。 ! panic的参数是一个空接口类型 interface{},所以任意类型的变量都可以传递给 panic(xxx) ! panic 不但可以在函数正常流程中抛出,在 defer 逻辑里也可以再次调用 panic 或抛出 panic a defer 里面的 panic 能够被后续执行的 defer 捕获。 recover()用来捕获 panic,阻止panic继续向上传递recover()和defer一起使用 ,但是recover() 只 有在defer后面的函数体内被直接调用才能捕获panic终止异常否则返回 nil,异常继续向外传递
//这会获取失败 defer recover() defer fmt.println(recover()) //嵌套两层也会获取失败 defer func() { func(){ println("defer inner") recover() //无效 }() }
以下场景会获取成功
package main func f(){ defer func() { println("defer inner") recover() }() } func except() { recover() } func test(){ defer except() panic("test panic") } func main() { f() except() test() }
可以有多个panic被抛出,连续多个panic的场景只能出现在延迟调用里面,否则不会出现多个panic被抛出的场景。但只有最后一次panic能被捕获
package main import "fmt" func main(){ defer func() { if err :=recover();err !=nil{ fmt.Println(err) } }() //只有最后一次panic调用被捕获 defer func() { panic("first defer panic") //打印结构是这个 }() defer func() { panic("second defer panic"