ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Go语言中常见100问题-#51 Comparing an error value inaccurately

2022-06-21 23:01:12  阅读:160  来源: 互联网

标签:返回 err errors -# 错误 ErrNoRows 51 value error


下面定义了一个全局的error,通常error变量命名以Err开头,后面是错误类型. 哨兵error期望描述的是一个预期的错误,下面以SQL库为例进行说明。

import "errors"

var ErrFoo = errors.New("foo")

设计一个查询数据库的Query方法,该方法返回结果是一个rows切片。在遇到查询结果为空的时候,怎么处理呢?有两个处理方法:

  • 返回一个特殊的标记值,返回nil切片(像标准库中的strings.Index方法,如果子串不存在,返回-1表示)
  • 返回一个具体的错误,调用方检查返回的error来进行判断

我们关注第二种方法,如果查询的结果为空,返回一个具体的错误。这是一种预期的问题,返回给调用方一个预期的错误用以区分这种情况。然而,在某些情况下,有些错误是难以提前确定的,像网络连接错误。我们并不是不想处理这种错误,而是因为它反映的是不同含义的问题。

在Go标准库中,可以看到不少这种通过哨兵标记错误的例子。

  • sql.ErrNoRows: 查询数据库数据为空的时候返回(就是前面说的例子)
  • io.EOF:io.Reader在没有输入数据的时候返回

上面是哨兵error想表达的一般原则,返回调用方期望检查的预期错误。因此,有以下准则:

  • 预期的error应该设计成值(哨兵error):var ErrFoo=errors.New("foo")
  • 无法预期的error设计成类型(通过type判断):type BarError struct{ … }, BarError类型实现error接口

现在分析一个共性的错误。如何比较error? 像下面的代码,可以使用==操作符

err := query()
if err != nil {
        if err == sql.ErrNoRows {
                // ...
        } else {
                // ...
        }
}

然而,在前面的问题Go语言中常见100问题-#49 wrap error中,error可以被包装。如果sql.ErrNoRows被使用fmt.Errorf+%w包装,err==sql.ErrNoRows将会永远不成立。Go1.13版本提供了解决方法。通过errors.As来检测wrap error是否是某种类型,同理,通过errors.Is来检测wrap error的值是否是某个具体的错误。改写后的代码为:

err := query()
if err != nil {
        if errors.Is(err, sql.ErrNoRows) {
                // ...
        } else {
                // ...
        }
}

使用errors.Is替换==比较错误是最佳的做法,因为它也能处理wrap error的情况。

总结,在程序中使用了fmt.Errorf+%w来包装错误,在检查error的时候不能用==,而是用errors.Is, errors.Is会递归的unwrap error检查每层中的error是否是要比较的。

 

标签:返回,err,errors,-#,错误,ErrNoRows,51,value,error
来源: https://www.cnblogs.com/tracydzf/p/16398703.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有