为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
ITMISS 2022-07-11 10:20:57
我试图找到正确的比较方法errors,发现了一些奇怪的行为type errorOne struct{}func (e errorOne) Error() string {    return "Error One"}e1 := errorOne{}e2 := fmt.Errorf("E2: %w", errorOne{}) // return 'error' interfaceres1 := e1 == e2          // falseres2 := errors.Is(e1, e2) // falseres3 := errors.Is(e2, e1) // true看起来errors.Is(...)不是对称的(或者我不理解方法行为)。怎么了?
查看完整描述

2 回答

?
慕侠2389804

TA贡献1719条经验 获得超6个赞

文档中:

报告 err 链中的任何错误是否与目标匹配。该链由 err 本身和通过重复调用 Unwrap 获得的错误序列组成。

因此,虽然您可以 unwrape2以检索e1,但如果您 unwrap e1e2则不在链中。


查看完整回答
反对 回复 2022-07-11
?
万千封印

TA贡献1891条经验 获得超3个赞

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 One

Error One

<nil>

第三行是<nil>因为errors.Unwrap(e2)返回e1(更具体地说是 的副本e1),并且它不包含任何错误。


查看完整回答
反对 回复 2022-07-11
  • 2 回答
  • 0 关注
  • 167 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号