Go 异常处理 defer panic recover
Go语言追求简洁优雅,所以,Go语言不支持传统的
try…catch…finally
这种异常,因为Go语言的设计者们认为,将异常与控制结构混在一起会很容易使得代码变得混乱。因为开发者很容易滥用异常,甚至一个小小的错误都抛出一个异常。
在Go语言中,使用多值返回来返回错误。不要用异常代替错误,更不要用来控制流程。在极个别的情况下,也就是说,遇到真正的异常的情况下(比如除数为0了)。才使用Go中引入的Exception处理:defer
, panic
, recover
。
这几个异常的使用场景可以这么简单描述:Go中可以抛出一个 panic
的异常,然后在 defer
中通过 recover
捕获这个异常,然后正常处理。
defer
defer 英文原意: vi. 推迟;延期;服从 vt. 使推迟;使延期。
defer 用于定义函数结束后的执行语句,类似析构函数。
- defer 语句添加的是函数,可以添加多次形成一个 defer 栈,后添加的 defer 语句在函数结束时先执行。
- defer 可以用来修改函数返回值
panic
panic 英文原意:n. 恐慌,惊慌;大恐慌 adj. 恐慌的;没有理由的 vt. 使恐慌 vi. 十分惊慌
panic 用来表示非常严重不可恢复的异常。
- 函数执行时遇到了 panic,函数便不能够往下执行了。但 panic 并不是立刻向上传递,而是到 defer 那,等 defer 中程序都执行完后再向上传递。
recover
recover 英文原意: vt. 恢复;弥补;重新获得 vi. 恢复;胜诉;重新得球 n. 还原至预备姿势
recover 用于捕获 panic。
- 程序遇到 panic 便到 defer 那,若 defer 中有 recover 函数对 panic 进行捕获,panic 便不会向上传递了。
Note:即便 panic 被 defer 中的 recover() 捕获了,程序流程已经到了 defer 中,逻辑不会恢复到 panic 哪个点上去
代码示例
package main
import "fmt"
func main(){
defer func(){ // 必须要先声明defer,否则不能捕获到panic异常
fmt.Println("c")
if err:=recover();err!=nil{
fmt.Println(err) // 这里的err其实就是panic传入的内容,55
}
fmt.Println("d")
}()
f()
}
func f(){
fmt.Println("a")
panic(55)
fmt.Println("b")
fmt.Println("f")
}
a
c
55
d
exit code 0, process exited normally.