type
status
date
slug
summary
tags
category
icon
password
overview
Go中的错误本质是一个interface变量
对于一个错误,我们的处理逻辑是这样的:先判断,比如它是否是一个我们已知的错误,再处理,比如打印错误信息等。
本文将对这两部分进行探讨。
判断
Go对错误的判断有两种:errors.Is, errors.As
以下我们分别来看一下两个函数的形式,作用和用法
errors.Is
errors.Is接受两个error类型的参数,它将判断target是否匹配err tree上的某节点;
什么是error tree?首先要理解,错误是可以不断包装的,比如下面这样:
这里我们利用fmt.Errorf,实现了对原始error的不断包装,而这一层层的包装就形成了error tree;
当我们使用errors.Is时,函数内部会调用unwrap方法,不断的对error tree进行解封装,直到遇到的error就是我们传入的target,假如解到最后也不符合target,那就会返回false;
比如:
errors.As
errors.As接受一个error类型的err和any类型的target,它的作用就是判断err tree上是否存在与target同一类型的error
比如:
以上例子中,我们自定义了一个错误类型DatabaseError,当err tree上有节点符合这个类型时,它返回true,否则返回false;
使用场景
当我们需要对一个确切的错误与error tree进行匹配时,我们使用errors.Is;
当我们需要进行的是类型的匹配时(尤其是自定义类型),我们使用errors.As。
处理
常规的error处理一般形式就是打日志,返回错误信息,但是当遇到一些关键性的错误时,往往要用panic及recover机制;
panic
panic语句使得当前函数立即终止,同时它还具有传播性,比如函数A调用了函数B,函数B遇到panic,会不断传播,使得A也停止,直到main函数panic掉,程序退出;
recover
前面说过,panic会不断传播,而reover会终止这个传播,夺回程序控制权,比如之前那个AB函数的例子,假如A中有一个recover函数,那么panic传播到A时,便被recover截获,不会再传播,而此时程序会运行上面代码中s处的处理逻辑。
值得注意的是,panic与recover只应该用于严重错误的处理,常规错误使用panic代价巨大,毕竟整个程序都会停掉。
- 作者:Alex
- 链接:https://nextme.one/wureny.eth/article/goerror1
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。