将 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) } }
输出
&{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中文网其他相关文章!