目录
摘要
defer,defer 栈,改变返回值,panic,recover
defer 与异常处理
概述
- Go 没有
try..catch
这种异常机制,而是使用panic
和recover
。 panic
在任何地方都可以执行,recover
只有在defer
调用的函数中才有效。
defer
defer
用于定义在函数执行结束后执行的语句- 多个
defer
会形成defer 栈
,后定义的defer
语句会被最先调用 - 即使函数发生严重错误也会执行
- 通过与匿名函数配合可以在 return 之后修改结果
定义多个 defer
func testDefer() {
fmt.Println("a")
defer fmt.Println("b")
defer fmt.Println("c")
defer func() {
fmt.Println("d")
}()
}
testDefer() //a d c b
改变返回值
由于 defer 在函数执行结束后执行,所以可以用于改变命名返回值的值
错误的用法
func changeResult(x int) int {
defer func() {
x++ //返回的值,改变变量没有用
}()
return x
}
x = changeResult(8)
fmt.Println("x", x) //x 8
正确的用法
func changeResult2(x int) (result int) {
defer func() {
result++
}()
return x
}
x = changeResult2(8)
fmt.Println("x", x) //x 9
panic 与 recover
panic
用于向上传递异常,执行在defer
之后,表示非常严重不可恢复的异常,会导致程序挂掉recover
可以对panic
进行捕获,使panic
停止向上传递
使用 panic
func one() { fmt.Println("func one") }
func two() { fmt.Println("func two") }
func broken() {
one()
panic("func broken with Panic")
two()
}
broken()
输出
func one
panic: func broken with Panic
异常消息...程序中断
使用 recover
func one() { fmt.Println("func one") }
func two() { fmt.Println("func two") }
func catch() {
one()
defer func() {
if err := recover(); err != nil {
fmt.Println("func catch with Recover")
}
}()
panic("func broken with Panic")
two()
}
catch()
输出
func one
func catch with Recover
注意
defer
需要放在panic
之前定义recover
之后,逻辑并不会恢复到panic
那个点去,函数还是会在defer
之后返回
有疑问加站长微信联系(非本文作者)