ホームページ > バックエンド開発 > Golang > UnmarshalJSON 内で json.Unmarshal を使用するときにスタック オーバーフローを回避するにはどうすればよいですか?

UnmarshalJSON 内で json.Unmarshal を使用するときにスタック オーバーフローを回避するにはどうすればよいですか?

Barbara Streisand
リリース: 2024-12-19 22:50:15
オリジナル
112 人が閲覧しました

How to Avoid Stack Overflow When Using json.Unmarshal Inside UnmarshalJSON?

スタック オーバーフローを伴わない UnmarshalJSON 関数内での json.Unmarshal の呼び出し

カスタム UnmarshalJSON 実装では、json.Unmarshal(b, type) を呼び出すと、スタックオーバーフローします。これは、JSON デコーダがカスタム UnmarshalJSON 実装を繰り返しチェックし、無限の再帰が発生するために発生します。

この問題を回避するには、type キーワードを使用して新しい型を作成し、型変換を使用して元の値をそれに割り当てます。これは、新しい型が元の型を基礎となる型として持つため可能です。

例:

Age フィールドを持つ Person 型があるとします。 Age が負にならないようにするには、次のように UnmarshalJSON を実装します。

type Person struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}

func (p *Person) UnmarshalJSON(data []byte) error {
    type person2 Person
    if err := json.Unmarshal(data, (*person2)(p)); err != nil {
        return err
    }

    // Post-processing after unmarshaling:
    if p.Age < 0 {
        p.Age = 0
    }
    return nil
}
ログイン後にコピー

このアプローチでは、person2 型はメソッドなしで新しい型を作成し、再帰を防ぎます。データがアンマーシャリングされると、そのデータは person2 タイプに割り当てられ、次に元の person タイプに割り当てられ、後処理が可能になります。

テスト:

import (
    "encoding/json"
    "fmt"
)

func main() {
    var p *Person
    fmt.Println(json.Unmarshal([]byte(`{"name":"Bob","age":10}`), &p))
    fmt.Println(p)

    fmt.Println(json.Unmarshal([]byte(`{"name":"Bob","age":-1}`), &p))
    fmt.Println(p)
}
ログイン後にコピー

出力:

<nil>
&{Bob 10}
<nil>
&{Bob 0}
ログイン後にコピー

これはカスタマイズ方法を示していますスタック オーバーフローを発生させずに JSON をアンマーシャルします。

以上がUnmarshalJSON 内で json.Unmarshal を使用するときにスタック オーバーフローを回避するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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