亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用errors.Is()進行錯誤換行/解包&&類型檢查

使用errors.Is()進行錯誤換行/解包&&類型檢查

Go
呼如林 2022-06-13 10:56:00
我正在檢查 Go v1.13 Go v1.14 中的錯誤跟蹤。為什么似乎只能找到沒有參數或帶有值接收器的錯誤實現errors.Is()?這意味著能夠包裝的錯誤實現必須有一個值接收器才能被errors.Is().package mainimport (    "fmt"    "errors")type someAtomicError struct {}func (e *someAtomicError) Error() string { return "Hi!" }func checkAtomicError() {    e := &someAtomicError{}    e2 := fmt.Errorf("whoa!: %w", e)    e2IsE := errors.Is(e2, &someAtomicError{})    fmt.Println("atomic error trace ---\t\t", e2, "\t\t--- is traceable: ", e2IsE)}type someWrapperError struct {    Msg string    Err error}func (e someWrapperError) Error() string { return fmt.Sprintf("%s: %v", e.Msg, e.Err) }func (e someWrapperError) Unwrap() error { return e.Err }func checkWrapperError() {    e := someWrapperError{"Hi!", nil}    e2 := fmt.Errorf("whoa!: %w", e)    e2IsE := errors.Is(e2, someWrapperError{"Hi!", nil})    fmt.Println("wrapper error trace ---\t\t", e2, "\t--- is traceable: ", e2IsE)}type somePointerWrapperError struct {    Msg string    Err error}func (e *somePointerWrapperError) Error() string { return fmt.Sprintf("%s: %v", e.Msg, e.Err) }func (e *somePointerWrapperError) Unwrap() error { return e.Err }func checkPointerWrapperError() {    e := &somePointerWrapperError{"Hi!", nil}    e2 := fmt.Errorf("whoa!: %w", e)    e2IsE := errors.Is(e2, &somePointerWrapperError{"Hi!", nil})    fmt.Println("pointer wrapper error trace ---\t", e2, "\t--- is traceable: ", e2IsE)}func main() {    checkAtomicError()    checkWrapperError()     checkPointerWrapperError()}//atomic error trace ---         whoa!: Hi!         --- is traceable:  true//wrapper error trace ---        whoa!: Hi!: <nil>  --- is traceable:  true//pointer wrapper error trace ---    whoa!: Hi!: <nil>  --- is traceable:  falsehttps://play.golang.org/p/-hSukZ-gii2似乎參數的任何差異,包括包裝的錯誤參數,Err都會導致無法找到類型errors.Is()。
查看完整描述

2 回答

?
qq_笑_17

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


查看完整回答
反對 回復 2022-06-13
?
泛舟湖上清波郎朗

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

}


查看完整回答
反對 回復 2022-06-13
  • 2 回答
  • 0 關注
  • 294 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號