2 回答
TA贡献1818条经验 获得超7个赞
false您在尝试在另一个通过中查找一个错误时得到的原因errors.Is是因为 - 虽然这两个错误可能具有相同的字段值 - 它们是两个不同的内存指针:
e := &somePointerWrapperError{"Hi!", nil}
e2 := &somePointerWrapperError{"Hi!", nil} // e2 != e
ew := fmt.Errorf("whoa!: %w", e)
errors.Is(ew, e) // true
errors.Is(ew, e2) // false - because `ew` wraps `e` not `e2`
那么如何检测这种“类型”的错误并获取它的值:errors.As改用:
e := &somePointerWrapperError{"Hi!", nil}
e2 := fmt.Errorf("whoa!: %w", e)
var ev *somePointerWrapperError
if errors.As(e2, &ev) {
fmt.Printf("%#v\n", ev) // &somePointerWrapperError{Msg:"Hi!", Err:error(nil)}
}
https://play.golang.org/p/CttKThLasXD
TA贡献1818条经验 获得超3个赞
远程相关,但可能对某人有所帮助:我花了一些时间才意识到errors.As(...)实际上需要一个指向目标的双指针,而errors.Is(...)没有:
var _ error = (*CustomError)(nil) // ensure CustomError implements error
type CustomError struct {
msg string
}
func (e CustomError) Error() string {
return e.msg
}
func main() {
err := &CustomError{"Hello, world!"} // Methods return pointers to errors, allowing them to be nil
var eval *CustomError
as := errors.As(err, &eval) // yes, that's **CustomError
asFaulty := errors.As(err, eval) // no compile error, so it wrongly seems okay
is := errors.Is(err, eval) // that's just *CustomError
fmt.Printf("as: %t, asFaulty: %t, is: %t", as, asFaulty, is) // as: true, asFaulty: false, is: true
}
- 2 回答
- 0 关注
- 325 浏览
添加回答
举报
