go学习笔记(13)-基本语法-defer 与异常处理
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之后返回

浙公网安备 33010602011771号