panic
- Go 采用明确的 error 值和类似异常的 panic 机制的方式作为独有的错误处理机制。
-
Go中可以抛出一个panic的异常,然后在defer中通过recover捕获这个异常,然后正常处理
。 -
由于 panic 会引起程序的崩溃,因此 panic 一般用于严重错误,如程序内部的逻辑不一致
。 当 panic() 触发的宕机发生时,panic() 后面的代码将不会被运行,但是在 panic() 函数前面已经运行过的 defer 语句依然会在宕机发生时发生作用
recover
在其他语言里,宕机往往以异常的形式存在,底层抛出异常,上层逻辑通过 try/catch 机制捕获异常,没有被捕获的严重异常会导致宕机,捕获的异常可以被忽略,让代码继续运行。
Go语言没有异常系统,其使用 panic 触发宕机类似于其他语言的抛出异常,recover 的宕机恢复机制就对应其他语言中的 try/catch 机制。
panic 和 recover 的关系
有 panic 没 recover,程序宕机
。
有 panic 也有 recover,程序不会宕机
,执行完对应的 defer 后,从宕机点退出当前函数后继续执行。recover()必须搭配defer使用,defer要在可能引发panic之前定义
func f1() {
fmt.Println("run f1")
}
func f2() {
fmt.Println("打开数据库连接...")
defer func(){
err := recover()
fmt.Println(err)
fmt.Println("释放数据库连接...")
}()
panic("出现严重错误!")
fmt.Println("run after")
}
func f3() {
fmt.Println("run f3")
}
func main() {
f1()
f2()
f3()
}
执行结果:
run f1
打开数据库连接...
出现严重错误!
释放数据库连接...
run f3
defer
- defer用来声明一个延迟函数,把这个函数放入到一个
栈
上, 当外部的包含方法return之前,返回参数到调用方法之前调用,也可以说是运行到最外层方法体的"}"时调用。我们经常用他来做一些资源的释放,比如关闭io操作 - 当有多个defer时执行顺序逆向的,
后进先出