go - 在 go 中键入断言错误

标签 go

我正在做一个小功能来检查 error针对某些类型并决定(取决于错误类型)某些重试是否值得。

我创建了自己的 temporary接口(interface)类型断言全部net/http实现此接口(interface)的错误(但是未导出,因此我也将其声明为我的代码)

type temporary interface {
    Temporary() bool
}

所以,我想在实现 temporary 时出现 net/http 错误时重试。接口(interface),以及如果错误是以下类型之一:io.EOF , io.ErrUnexpectedEOFErrTimeoutExceeded
在哪里

var ErrTimeoutExceeded = errors.New("timeout exceeded")

但是下面的 switch 语句


func isWorthRetrying(err error) bool {
    switch e := err.(type) {
    case temporary:
        return true
    case io.EOF:
        return true
    case io.ErrUnexpectedEOF:
        return true
    case ErrTimeoutExceeded:
        return true
    default:
        return false
    }
}

所有语句中的错误(除了针对 temporary 断言的一种类型)

有错误,例如

io.EOF (type error) is not a type



这是什么意思?

最佳答案

在您的 switch 语句中,您正在检查 err.(type) ,这是一种类型。值 io.EOF , io.ErrUnexpectedEOFErrTimeoutExceeded不是类型,它们是对象。您无法检查类型是否为对象(不同的事物);但是,您可以检查对象是否属于某个类型。

您可以使用以下代码检查这两种情况:

func isWorthRetrying(err error) bool {
        switch err.(type) {
        case temporary:
                return true
        default:
                switch err {
                case io.EOF:
                        return true
                case io.ErrUnexpectedEOF:
                        return true
                case ErrTimeoutExceeded:
                        return true
                default:
                        return false
                }
        }
}

编辑:感谢 Adrian 的评论,我们还可以使用新的 errors.Is 编写此函数,如果您使用的是 Go 1.13+:
func isWorthRetrying(err error) bool {
        switch err.(type) {
        case temporary:
                return true
        default:
                return errors.Is(err, io.EOF) ||
                        errors.Is(err, io.ErrUnexpectedEOF) ||
                        errors.Is(err, ErrTimeoutExceeded)
        }
}

关于go - 在 go 中键入断言错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61060270/

相关文章:

google-app-engine - 如果没有小数,Google Cloud Datastore 会将 float 存储为 int,我该如何解析它?

go - 测试使用 Gorilla/context 的处理程序

go - 如何检查对象是否具有特定方法?

go - 如何从 Go 中的另一个包导入结构

go - 在 Go 网络应用程序中加载 key 的最佳实践是什么?

postgresql - 在数据库上的每个api调用上,gorm范围都会继续添加到上一个

去超时不开火

git2go 获取远程标签

api - 如何通过名称获取特定的api,然后从此“Apis”结构列表中获取其ID?

mongodb - 带有聚合的 mgo,使用另一个查询和字段更改进行过滤