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

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

Susan Sarandon
リリース: 2024-12-12 14:52:10
オリジナル
572 人が閲覧しました

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 サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート