首頁 >後端開發 >Golang >如何在 Go 中實現真正的遞歸錯誤包裝和展開?

如何在 Go 中實現真正的遞歸錯誤包裝和展開?

Susan Sarandon
Susan Sarandon原創
2024-12-12 14:52:10572瀏覽

How Can I Achieve True Recursive Error Wrapping and Unwrapping in Go?

Go 中使用遞歸Is() 和As() 進行錯誤包裝

許多開發人員建議在Go 中使用fmt.Errorf 和%w 動詞來包裝錯誤,但是這個方法不提供真正的遞歸包裝。若要使用 Is() 和 As() 遞歸檢查錯誤,可以使用自訂錯誤類型。

遞歸的自訂錯誤類型

這裡有一個自訂錯誤類型errorChain,支援錯誤包裝和遞歸檢查:

type errorChain struct {
    err  error
    next *errorChain
}

func Wrap(errs ...error) error {
    out := errorChain{err: errs[0]}

    n := &out
    for _, err := range errs[1:] {
        n.next = &errorChain{err: err}
        n = n.next
    }
    return out
}

將Is() 和As( ) 新增至自訂類型

啟用遞歸檢查的關鍵是在自訂類型上實作Is() 和As()方法。這些方法允許對鏈中包含的錯誤進行錯誤比較,而不是鏈本身:

func (c errorChain) Is(err error) bool { return errors.Is(c.err, err) }

func (c errorChain) As(target any) bool { return errors.As(c.err, target) }

使用errorChain

使用這些方法,您可以包裝錯誤並執行遞歸檢查:

errs := Wrap(errors.New("error 0"), errors.New("error 1"), errors.New("error 2"))

fmt.Println(errors.Is(errs, errors.New("error 0")))  // true
fmt.Println(errors.Is(errs, errors.New("error 1")))  // true
fmt.Println(errors.Is(errs, errors.New("error 2")))  // true

使用Unwrap() 迭代Chain

errorChain 中的Unwrap() 方法可讓您遍歷鏈中包裝的錯誤:

var currentError error = errs
for {
    currentError = errors.Unwrap(currentError)
    if currentError == nil {
        break
    }
    fmt.Println(currentError)
}

此範例列印鏈中的所有錯誤:

error 0
error 1
error 2

以上是如何在 Go 中實現真正的遞歸錯誤包裝和展開?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn