ホームページ >バックエンド開発 >Golang >Go の「interface{}」パラメータに渡されたポインタ値と非ポインタ値で「json.Unmarshal」の動作が異なるのはなぜですか?

Go の「interface{}」パラメータに渡されたポインタ値と非ポインタ値で「json.Unmarshal」の動作が異なるのはなぜですか?

Susan Sarandon
Susan Sarandonオリジナル
2024-12-15 20:38:15787ブラウズ

Why Does `json.Unmarshal` Behave Differently with Pointer and Non-Pointer Values Passed to an `interface{}` Parameter in Go?

Golang インターフェイス{}の型の誤解

Go で関数パラメータの型としてインターフェイス{}を使用する場合、それがどのように行われるかを理解することが重要ですjson.Unmarshal の使用法に影響します。非ポインタ型をインターフェース パラメータに渡すと、予期しない結果が生じる可能性があります。

シナリオ 1: 非ポインタ値をインターフェースに渡す{}

In指定された例では、Test 構造体が、インターフェイスを期待するテスト関数に直接渡されます。{}パラメータ:

test(Test{})

出力は、構造体が json.Unmarshal:

main.Test
*interface {}
map[string]interface {}

によって map[string]interface{} に変換されたことを示しています。これは、interface{} がラップしているためです。 (値; 型) ペアであり、渡された値は非ポインターであるため、json パッケージはアンマーシャリングする新しい値を作成します。 JSON オブジェクトのデフォルトは map[string]interface{} であるため、これが作成されます。

シナリオ 2: インターフェイスにポインタを渡す{}

ただし、テスト関数への Test 構造体へのポインタは、期待される結果を生成します。 result:

test(&Test{})
*main.Test
*interface {}
*main.Test
&{bar}

これは、構造体へのポインターが json.Unmarshal に渡され、指定された Test 値に直接アンマーシャリングできるためです。

: ポインターとインターフェイス

パッケージに格納されている値を変更する必要がある場合インターフェース{}の場合、それへのポインタを受け取る必要があります。 json.Unmarshal の場合、アンマーシャリング先のポインターが必要です。すでにポインタをラップしているインターフェース値がある場合は、アドレスを再度取得せずにそのまま渡します。

ベスト プラクティス

インターフェースへのポインタの使用は避けてください。{}代わりに、ポインタをインターフェイス値でラップしてインターフェイスに挿入します。ポインタを保持するインターフェースを渡す必要がある場合は、それを直接渡してください。

以上がGo の「interface{}」パラメータに渡されたポインタ値と非ポインタ値で「json.Unmarshal」の動作が異なるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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