[转载]Go 语言之 panic 与 recover

转载自:https://blog.csdn.net/a41888313/article/details/79691728,作了使信息更加清晰化的修订。

error 类型

官方文档介绍:

error 官方文档介绍
error 这一内建的接口类型,是表示错误状况(可为 nil)的常规接口。

panic 函数

官方文档介绍:

panic 官方文档介绍

内建的 panic 函数停止当前 goroutine(协程)的正常执行。当函数 F 调用 panic 时,F 的正常执行立即停止。但是被 F 推迟的函数还都会执行,然后 F 返回到调用者。对于调用者 G 来说,F 的调用就像是调用了 panic 一样,终止 G 的执行并运行任何推迟(带有 defer 关键字)的函数。 这种情况会持续下去,直到正在执行的 goroutine 中所有的函数都以相反的顺序停止。 至此,程序终止,并报告错误情况(包括 panic 的参数值)。这种终止序列被称作 panicking,且可以通过内建的 recover 函数来控制。

recover 函数

官方文档介绍:

函数func 官方解释
recover 内置函数允许一段程序管理一个正在 paincking 的 goroutine 的行为。在被 defer 的函数(而非由其调用的任何函数)内部执行 recover 函数,可以恢复正常执行并获取到传递给 panic 调用的错误值,以此来停止 panicking 序列函数的执行。 如果在被 defer 的函数之外调用 recover,则不会停止 panicking 序列的执行。在此情况下,或者是在 goroutine 没有 panicking 时,或者是提供给 panic 的参数为 nil 时,recover 返回 nil。也就是说,recover 函数的返回值报告了协程是否正在遭遇 panicking 。

panic 函数就是往外扔错误,一层接一层往上扔直到当前程序不能运行为止,如果不想让 panic 函数扔的错误导致程序挂掉,就得使用 recover 函数来接收 panic 错误或者说是阻挡 panicking。recover  函数可以将错误转化为 error 类型。panic 错误并不会让 defer 关键字声明的函数也停止运行,也就是说,defer 关键字声明的函数或者代码即使遇到错误也会执行。

一个函数里面有 defer 关键字声明一个函数(假设叫 catch 函数)和会运行出错的代码,在 catch 函数里面调用 recover 函数,recover 会拦截错误,不让错误往上扔,返回给调用者 error(里面有错误的信息)类型 ,从而使 goroutine 不挂掉。

运行结果:

当 panic 函数执行的时候导致后面函数 afterPanic() 不能执行,main 函数也抛出一个错误,整个程序异常退出。

取消代码中注释掉的 defer 关键字调用 catch 函数,程序运行结果:

分析:程序正常结束,没有因为 panic(错误)而到导致程序终止挂掉,且后面的 afterPanic() 也执行了。错误被 recover 函数捕获,转化为 error 类型的错误后输出“catch(): 转为 error 后:”panic 错误” ”。

一般情况下,不会采用上面这种显式定义 catch 函数的写法,而是在发生 panic 的函数里面写一个匿名的 defer 函数,就可以拦截 panicking, 并且不让程序挂掉和显示错误信息:

最后如果想将错误信息返回给调用者,可以改为如下:

提前声明一个 error 类型的返回值变量,把错误信息转换到 error 变量,再将之返回给调用者即可。

发表评论

电子邮件地址不会被公开。 必填项已用*标注