ホームページ >バックエンド開発 >Golang >Go の `Is()` と `As()` は本当に再帰的エラーのラップ解除を提供しますか?

Go の `Is()` と `As()` は本当に再帰的エラーのラップ解除を提供しますか?

Patricia Arquette
Patricia Arquetteオリジナル
2024-12-15 19:29:10934ブラウズ

Does Go's `Is()` and `As()` Truly Offer Recursive Error Unwrapping?

Go のエラー処理再帰要求は正確ですか?

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

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