这是我参与「第五届青训营 」伴学笔记创作活动的第3天
编码规范 错误与异常处理
Go 语言为错误处理定义了一个标准模式,即 error 接口
简单错误
一般错误函数将错误类型作为第二个参数返回
func Foo(param int) (n int, err error) { // ... }
简单的错误指的是仅出现一次的错误,且在其他地方不需要捕获该错误
优先使用errors.New 来创建匿名函数来标出错误,格式化要求使用fmt.Errorf
func defaultfun()error{ return errors.New(" errors")//创建错误消息 }
错误的Wrap和Unwrap
错误的Wrap实际上提供了一个error嵌套另一个error的能力,从而生成一个error的跟踪链,在fmt.Errorf中使用:%w关键字来将一个错误关联至错误链中。
errors三个API和新的关键字format关键字
errors.ls errors.As, errors.Unwrap以及fmt.Errorf的%w
list,_, err :=c.GetBytes(cache.Subkey(a.actionID,"srcfiles"))
if err !=nil{
return fmt.Errorf("list:%w", err)//关联错误链
}
错误判定
判定一个特定错误需要使用errors.ls,不简单同于==此错误,其可以判断错误链上的所有错误是否具有特定错误 获取特定种类错误使用errors.As panic 不建议业务代码中使用,调用函数不包含recover会造成程序崩溃,建议使用error代替panic 程序启动阶段发生不可逆的错误时,可以在init或main函数panic recover 只能在被defer的函数中使用,嵌套无法生效,只在当前goroutime生效,deter的语句是后进先出。
func (s *ss) Token(skipSpace bool,f func(rune)bool)
(tok []byte,err error){
defer func(){
if e:=recover(); e !=nil{ //recover在defer中
if se,ok :=e.(scanError); ok{
err = se.err
}else{
panic(e)
}
}
}
}
debug.Stack()//记录当前调用栈
panic 用于真正异常的情况
error 尽可能提供简明的上下文信息,方便定位问题
recover 生效范围,在当前 goroutine 的被 defer 的函数中生效
然后在调用返回错误信息的函数/方法时,按照如下模板编写处理代码:
n, err := Foo(0)
if err != nil {
// 错误处理
} else {
// 使用返回值 n
}