ホームページ >バックエンド開発 >Golang >Go で動的型を使用して自己参照 JSON 文字列をアンマーシャリングする方法は?

Go で動的型を使用して自己参照 JSON 文字列をアンマーシャリングする方法は?

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-12-25 13:13:09142ブラウズ

How to Unmarshal a Self-Referential JSON String in Go with a Dynamic Type?

自己参照要素を持つ構造体への JSON 文字列のアンマーシャリング

Go では、JSON 文字列を自己参照要素を持つ構造体にアンマーシャリングします。参照要素は難しい場合があります。この問題に効果的に対処する具体的な例と解決策を見てみましょう。

JSON 入力と構造体定義

次の JSON 入力を考えてみましょう:

[{
    "db": {
        "url": "mongodb://localhost",
        "port": "27000",
        "uname": "",
        "pass": "",
        "authdb": "",
        "replicas": [
            {
                "rs01": {
                    "url":"mongodb://localhost",
                    "port": "27001",
                    "uname": "",
                    "pass": "",
                    "authdb": ""
                }
            },
            {
                "rs02": {
                    "url":"mongodb://localhost",
                    "port": "27002",
                    "uname": "",
                    "pass": "",
                    "authdb": ""
                }
            }
        ]
    }
}]

そして、対応する Go struct:

type DBS struct {
    URL      string   `json:"url"`
    Port     string   `json:"port"`
    Uname    string   `json:"uname"`
    Pass     string   `json:"pass"`
    Authdb   string   `json:"authdb"`
    Replicas []DBS     `json:"replicas"`
}

アンマーシャル関数と出力

提供された関数、loadConfigs() は、JSON 文字列を DBS 構造体のスライスにアンマーシャルしようとします:

func loadConfigs() []DBS {
    var config []DBS
    raw, err := ioutil.ReadFile("./config.json")
    if err != nil {
        fmt.Println(err.Error())
        os.Exit(1)
    }

    json.Unmarshal(raw, &config)
    return config
}

ただし、これにより空のスライス []DBS{ が生成されます。 JSON 入力は DBS 構造体のスライスではなく、オブジェクトの配列を含む JSON オブジェクト ラッパーです。

解決策: 動的型へのマッピング

JSON を完全に記述するには入力にはマップのような動的タイプが必要です。更新された型定義は次のようになります:

type DBSReplicated struct {
    DB *DBS `json:"db"`
}
type DBS struct {
    URL      string            `json:"url"`
    Port     string            `json:"port"`
    Uname    string            `json:"uname"`
    Pass     string            `json:"pass"`
    Authdb   string            `json:"authdb"`
    Replicas []map[string]*DBS `json:"replicas"`
}

この新しい型を使用すると、JSON 入力を正確に解析できます:

var dbs []*DBReplicated
if err := json.Unmarshal([]byte(src), &dbs); err != nil {
    panic(err)
}

db := dbs[0].DB
fmt.Printf("%+v\n", db)
for _, dbs := range db.Replicas {
    for name, replica := range dbs {
        fmt.Printf("%s: %+v\n", name, replica)
    }
}

Output

&{URL:mongodb://localhost Port:27000 Uname: Pass: Authdb: Replicas:[map[rs01:0x10538200] map[rs02:0x10538240]]}
rs01: &{URL:mongodb://localhost Port:27001 Uname: Pass: Authdb: Replicas:[]}
rs02: &{URL:mongodb://localhost Port:27002 Uname: Pass: Authdb: Replicas:[]}

キーポイント

  • 動的な JSON 入力をモデル化するにはマップ タイプを使用します。
  • JSON タグのプロパティ名の適切な構文に注意してください。
  • ポインターの使用を検討してください。構造体内でネストされた構造体を許可します。

以上がGo で動的型を使用して自己参照 JSON 文字列をアンマーシャリングする方法は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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