Go 錯誤:揭開Is() 和As() 的神秘面紗
在Go 中,錯誤處理對於提供有意義的診斷和分析至關重要。實施強而有力的計劃。 error 套件提供 Is() 和 As() 函數,分別用於確定錯誤相等性和提取特定細節。一個常見的誤解是這些函數支援遞歸錯誤包裝,從而能夠展開多個巢狀錯誤。
但是,經過仔細檢查,標準 fmt.Errorf 函數不提供遞歸錯誤包裝。這意味著使用 %w 包裝錯誤不允許完全遍歷錯誤鏈。
為了解決此問題,可以定義自訂錯誤類型來實作錯誤介面並實作自己的 Is() 和As() 方法。這允許遞歸展開多個巢狀錯誤。
範例:
type customError struct { err error wrapped *customError } func (c *customError) Error() string { if c.err != nil { return c.err.Error() } return "Custom error without cause" } func (c *customError) Is(err error) bool { if c.err != nil { return errors.Is(c.err, err) } return false } func (c *customError) As(target interface{}) bool { if c.err != nil { return errors.As(c.err, target) } return false } func Wrap(errs ...error) error { var rootError *customError for i := len(errs) - 1; i >= 0; i-- { rootError = &customError{ err: errs[i], wrapped: rootError, } } return rootError }
使用此自訂錯誤類型,您可以輕鬆包裝和展開多個錯誤並執行遞歸Is() 和As () 檢查:
err := Wrap(Err1, Err2, Err3) fmt.Println(errors.Is(err, Err1)) // true fmt.Println(errors.Is(err, Err3)) // false var errType ErrType errors.As(err, &errType) fmt.Println(errType) // "my error type"
雖然此自訂實作提供遞歸錯誤展開,但有目前,Go 標準庫中沒有內建類型可以提供開箱即用的此功能。然而,像 github.com/pkg/errors 這樣的函式庫提供了額外的錯誤處理功能,包括遞歸解包,這可能值得在您自己的專案中考慮。
以上是Go 的 Is() 和 As() 函數如何處理遞迴錯誤包裝?的詳細內容。更多資訊請關注PHP中文網其他相關文章!