Go异常处理
异常简介
一、异常分类
1.1、Panic
1、GO中Panic是一种系统级别的异常,一旦出现回终端程序的运行,来自运行时。并且当我们手动调用panic()
函数的时候也会触发这个异常。用于严重错误,此时不管出现在哪里Panic都会直接结束程序(除非进行恢复)
2、手动触发panic()
如下:
func main(){ |
当panic()
触发的时候,会立即在当前GO程中执行一个 defer[^1] ,并且其实际会输出详细的堆栈调用日志。
1.2、Error
1.2.1、errors.go
1、Error
在GO中默认使用返回值的方法进行返回,要不你接受这个错误进行处理,要不使用_
匿名接收这个错误不处理。
nil
:表示没有错误
2、手动抛出一个error
func main(){ |
3、errors
包
1、errors
源码如下:
package errors |
根据errors.go
我们可以按照他的方法自定义一个错误类型并且实现错误error
接口,实现自定义错误类型。
// error 接口 |
官方实例代码:
package errors_test |
1.2.2、warp.go
参考:
实际上包裹了一个
error
错误链,具体原理如下:
1.2.2.1、Unwrap(err error) error
Unwrap(err error) error :获取内层的error,返回错误根本原因
- 包装Error:fmt.Errorf 来包装 error,需要使用 %w 的格式化
return fmt.Errorf("add error info: %+v, origin error: %w", "other info", err)
- 解包Error
源码:func Unwrap(err error) error {
//断言转化 err类型为一个实现了Unwarp()方法的interface对象
u, ok := err.(interface {
Unwrap() error
})
//断言失败
if !ok {
return nil
}
//继续解包
return u.Unwrap()
}
1.2.2.2、Is(err, target error) bool
Is(err, target error) bool :查看调用链是否与包含target错误
源码:
func Is(err, target error) bool { |
1.2.2.3、As(err error, target interface{}) bool
As(err error, target interface{}) bool : 剥离到给定target并将target设置到属性中去
源码:
func As(err error, target any) bool { |
二、异常处理
2.1、Panic
在Panic错误中一半使用recover函数进行恢复整个已经崩溃的程序进程,但是必须在defer
中进行调用,才会生效。并且在函数调用的过程中可以在每个函数中都抛出panic
逐层向外,直到不能捕获就会结束。
- 有 panic 没 recover ,程序宕机。
- 有 panic 有 recover ,程序正常。
使用方法:
func main(){ |
2.2、Error
在GO语言中不存在传统意义上面try -catch
语句,其设计思想如下:
- 函数出现异常,就会将异常作为返回值,不存在异常的时候就会返回
nil
- 在外部应该使用
if
进行捕获异常进行处理
err,ans = ErrorDemo() |
三、优雅异常处理
#todo
- 优雅的异常处理
[^1]: defer_语句会将其后面跟随的语句进行延迟处理,在 defer 归属的函数即将返回时,将延迟处理的语句按 defer 的逆序进行执行(多个执行入栈,出栈)