Go 的錯誤處理函數 Is() 和 As() 宣告是遞歸的,能夠解開多個巢狀錯誤。但是,尚不清楚是否存在實現錯誤介面並支援此遞歸功能而不會出現問題的內建類型。
有缺陷的自訂實作
嘗試建立自訂錯誤類型經常遇到問題,因為 Go 中的錯誤是按位址進行比較的。將錯誤包裝為指標的自訂類型會導致意外行為,例如修改後的父錯誤會影響後續包裝。
可行的解決方案
更強大的解決方案涉及創建一個新的錯誤類型,errorChain。此類型包含一個 err 欄位來儲存目前錯誤,以及一個 next 欄位來引用鏈中的下一個錯誤。此外,它還實作了 Is() 和 As() 方法來促進遞迴錯誤展開。
包裝和展開
Wrap() 函數接受多個錯誤,建立一個 errorChain 對象,並將它們連結在一起。 Unwrap() 函數遍歷鏈,傳回序列中的下一個錯誤。
範例
使用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 } func (c errorChain) Is(err error) bool { return c.err == err } func (c errorChain) As(target any) bool { return errors.As(c.err, target) }
遊樂場: https://go .dev/play/p/6BYGgIb728k
以上是Go 的 Is() 和 As() 真的提供遞歸錯誤解包嗎?的詳細內容。更多資訊請關注PHP中文網其他相關文章!