ホームページ >バックエンド開発 >Golang >Go で真の再帰的エラーのラップとラップ解除を実現するにはどうすればよいですか?

Go で真の再帰的エラーのラップとラップ解除を実現するにはどうすればよいですか?

Susan Sarandon
Susan Sarandonオリジナル
2024-12-12 14:52:10586ブラウズ

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

Go での再帰 Is() と As() によるエラー ラップ

多くの開発者は、%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() の追加Type

再帰的チェックを有効にする鍵は、カスタム型に 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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。