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 關注
- 294 瀏覽
添加回答
舉報