「这是我参与2022首次更文挑战的第24天,活动详情查看:2022首次更文挑战」。
0 环境
- 系统环境:win10
- 编辑器:vscode
- go版本:gol.17.3
- 参考文章:go语言中文文档
1 error断言
和接口中的断言类似,它那是定义一个接口变量,接口变量.(接收者类型)断言。而这里是先获取到错误返回值(假如没有实现接口,运行断言时,会报错缺少接口类型的。),在通过错误返回值.(类型)断言,判断是否为空,编写相对应的代码。如下代码:虽然在
assertAddHeight1()中,error1它是universalError指针类型,但universalError指针类型已经实现了error接口,这也可以说明addHeight1()返回值类型可以用error定义的原因。
type universalError struct {
// 错误状态
errorStatus int
// 错误信息
errorMsg string
}
func (ue *universalError) Error() string {
return ue.errorMsg
}
func addHeight1(heightMin, heightMax int) (int, error) {
if heightMin < 150 || heightMax < 180 {
return 150,&universalError{
errorStatus: 400,
errorMsg: "heightMin不能小于150,heightMax不能小于180",
}
} else {
return heightMin + heightMax, nil
}
}
func assertAddHeight1() {
sum, error1 := addHeight1(149,181)
ue, result := error1.(*universalError)
if result {
fmt.Println("错误状态 -->", ue.errorStatus,"\n错误信息 -->", ue.errorMsg)
} else {
fmt.Println(sum)
}
}
func main() {
assertAddHeight1()
}
2 错误嵌套
1 Error Wrapping(合)
上面的自定义错误,需要实现错误接口,在返回错误信息。现在呢,变了,需要多个错误共存,不仅仅只有这一个错误信息,在不改变这个错误信息的情况下,在新建出来新的错误,拓展(嵌套)多个error,但是之前的方式是:先定义结构体,在里面不停拓展,在用接口实现它,可以但太过麻烦了,有么有更好的方式呢?
Error Wrapping它来了,一股浓厚的借鸡生蛋的味道,在鸡窝里,借鸡(已有的错误)生蛋(新的错误),最终的结果是:既有鸡(已有的错误),还有新鲜美味的蛋(新的错误),也就是:已有的错误和新的错误共存。
fmt.Errorf函数里加个%w,对了,里面的那种鸡,我没写错哦,是那种鸡。
2 errors.Unwrap函数(解)
如果说上面的
Error Wrapping是给鸡下套(包裹嵌套),那errors.Unwrap就是给鸡解套。
3 errors.Is函数(判断)
判断两个
error是否相同(判断第一个参数是否相等/包含第二个参数)。假设 鸡 蛋代表嵌套error,鸡代表原来的错误。比如Is传入a,b两个参数,Is(a, b) --> a包含b则为true,(鸡 蛋,鸡),而false,(鸡, 鸡 蛋)肯定不包含呀。
4 errors.As函数(断言)
当有了嵌套error后,之前的断言就不能用,这时替代品
errors.As()出现了。
改写上面error断言的例子,用As来实现。
3 总结
首先学习了error的断言,虽然和自定义接口的断言有区别,但也需要实现error接口并且返回值为error。面对多个error,并且需要在旧的错误的基本上,添加新的错误,保证新旧共存,error的嵌套帮我们很好的解决了这个问题,它提供了嵌套和解套,以及error的相同判断和嵌套error断言的写法(之前的断言不在适用)。