多くの開発者は、%w 動詞を指定した fmt.Errorf を使用して Go でエラーをラップすることを推奨していますが、これはこのメソッドは真の再帰的ラッピングを提供しません。 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() メソッドの両方を実装することです。これらのメソッドを使用すると、チェーン自体ではなく、チェーン内に含まれるエラーでのエラー比較が可能になります。
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) }
これらのメソッドを使用すると、エラーをラップして再帰的チェックを実行できます。 :
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
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 中国語 Web サイトの他の関連記事を参照してください。