Go エラー: Is() と As() の謎を解明する
Go では、エラー処理は意味のある診断と結果を提供するために重要です。堅牢なプログラムを実装します。エラー パッケージには、エラーの同等性を判断するための Is() 関数と特定の詳細を抽出するための As() 関数が用意されています。よくある誤解の 1 つは、これらの関数が再帰的エラー ラッピングをサポートし、複数のネストされたエラーのラップ解除を可能にするというものです。
しかし、詳しく調べてみると、標準の 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 中国語 Web サイトの他の関連記事を参照してください。