猿问

错误。Is(...) 不是对称的?

我试图找到正确的比较方法errors,发现了一些奇怪的行为


type errorOne struct{}


func (e errorOne) Error() string {

    return "Error One"

}

e1 := errorOne{}

e2 := fmt.Errorf("E2: %w", errorOne{}) // return 'error' interface

res1 := e1 == e2          // false

res2 := errors.Is(e1, e2) // false

res3 := errors.Is(e2, e1) // true

看起来errors.Is(...)不是对称的(或者我不理解方法行为)。


怎么了?


ITMISS
浏览 168回答 2
2回答

慕侠2389804

从文档中:报告 err 链中的任何错误是否与目标匹配。该链由 err 本身和通过重复调用 Unwrap 获得的错误序列组成。因此,虽然您可以 unwrape2以检索e1,但如果您 unwrap e1,e2则不在链中。

万千封印

errors.Is()不是“等于”实现,而是“是否包装”检查。e2换行e1,但e1不换行e2。那么为什么会errors.Is()是对称的呢?“环绕”是一种单向关系;例如,有母女关系,但母亲的母亲不是她的女儿。一个包装的错误可能被另一个包装,创建一个“链”。errors.Is()基本上告诉您给定的错误是否是该“链”的一部分。请注意,您可以使用“提取”包装的错误errors.Unwrap(),例如:fmt.Println(e2)fmt.Println(errors.Unwrap(e2))fmt.Println(errors.Unwrap(errors.Unwrap(e2)))这将输出(在Go Playground上尝试):E2: Error OneError One<nil>第三行是<nil>因为errors.Unwrap(e2)返回e1(更具体地说是 的副本e1),并且它不包含任何错误。
随时随地看视频慕课网APP

相关分类

Go
我要回答