ホームページ  >  記事  >  バックエンド開発  >  Go でインターフェイスを操作するときに JSON Unmarshal が構造体ではなくマップを返すのはなぜですか?

Go でインターフェイスを操作するときに JSON Unmarshal が構造体ではなくマップを返すのはなぜですか?

Barbara Streisand
Barbara Streisandオリジナル
2024-10-25 09:26:02605ブラウズ

Why Does JSON Unmarshal Return a Map Instead of a Struct in Go When Working with Interfaces?

意図した構造体の代わりにマップを返す JSON アンマーシャリングの背後にある謎

Go での JSON アンマーシャリングは、インターフェイスと構造体を扱うときに課題を引き起こす可能性があります。開発者は、次のスニペットの場合のように、アンマーシャル プロセスで予期した構造体ではなくマップが生成される状況に遭遇することがあります。

<code class="go">import "encoding/json"
import "fmt"
import "reflect"

func main() {
    type Ping struct {
        ID int `json:"id"`
    }
    var ping interface{} = Ping{}
    if err := json.Unmarshal([]byte(`{"id":42}`), &ping); err != nil {
        panic(err)
    }
    fmt.Println("Unexpected:", ping) // Result: map[id:42]
}</code>

この動作の根本的な理由は、インターフェイスの抽象的な性質にあります。 JSON アンマーシャリングがインターフェイスで実行されると、結果は基になる型のフィールドを表すマップになります。上の例では、インターフェイス Ping は単一のキーと値のペア {"id":42} を持つマップを保持しています。

この問題を修正して目的の構造体を取得するには、ポインターを渡すことが重要です。特定の構造体タイプへ:

<code class="go">type Ping struct {
    ID int `json:"id"`
}
func main() {
    var ping Ping
    if err := json.Unmarshal([]byte(`{"id":42}`), &ping); err != nil {
        panic(err)
    }
    fmt.Println("Success:", ping) // Result: {42}
}</code>

ポインターを Ping に渡すことにより、JSON アンマーシャル プロセスは、マップを作成するのではなく、構造体のインスタンスを作成し、そのフィールドにデータを設定するように指示されます。

また、具体的な構造体へのポインタが利用できない場合は、リフレクションを使用してポインタを動的に作成し、その後その値をインターフェイスに割り当てることができます:

<code class="go">import "reflect"

func main() {
    var ping interface{} = Ping{}
    nptr := reflect.New(reflect.TypeOf(ping))
    if err := json.Unmarshal([]byte(`{"id":42}`), nptr.Interface()); err != nil {
        panic(err)
    }
    ping = nptr.Elem().Interface()
    fmt.Println("Reflect-Based:", ping) // Result: {42}
}</code>

以上がGo でインターフェイスを操作するときに JSON Unmarshal が構造体ではなくマップを返すのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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