自己参照要素を持つ構造体への 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:[]}
キーポイント
以上がGo で動的型を使用して自己参照 JSON 文字列をアンマーシャリングする方法は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。