如何在Go语言中获取JSON结构内多层嵌套列表的字段值
解决方案
Go语言处理JSON优先推荐用结构体绑定的方式,类型安全且代码易维护,也可以基于你现有的动态类型断言逻辑扩展实现。
推荐方案:预定义结构体反序列化
首先定义和JSON结构匹配的结构体,直接反序列化为结构体对象后即可直接访问字段:
package main import ( "encoding/json" "fmt" ) // 定义和JSON匹配的结构体 type UserData struct { UserID string `json:"userid"` Username string `json:"username"` RegisteredDate string `json:"registered_date"` } type Person struct { Name string `json:"name"` Surname string `json:"surname"` Data []UserData `json:"data"` } type Response struct { Persons []Person `json:"persons"` } func main() { // 你的JSON数据 data := `{ "persons":[ { "name":"mark", "surname":"zuckerberg", "data":[ { "userid":"09210", "username":"mark290", "registered_date":"10-01-2017" }, { "userid":"092240", "username":"mark291", "registered_date":"11-01-2017" } ] }, { "name":"bill", "surname":"clinton", "data":[ { "userid":"0442340", "username":"billy", "registered_date":"10-01-2000" }, { "userid":"89472894", "username":"billary", "registered_date":"11-01-2015" } ] } ] }` var resp Response err := json.Unmarshal([]byte(data), &resp) if err != nil { fmt.Println("反序列化失败:", err) return } // 遍历提取username for _, person := range resp.Persons { fmt.Printf("人员:%s %s 的用户名列表:\n", person.Name, person.Surname) for _, d := range person.Data { fmt.Println("-", d.Username) } } }
运行后会直接输出所有人员对应的用户名。
现有代码的修改方案
如果你要继续使用interface{}动态解析的方式,只需要在拿到data字段后继续遍历,做对应类型断言即可:
j := []byte(data) var f interface{} err := json.Unmarshal(j, &f) if err != nil { fmt.Println("反序列化失败:", err) return } rootMap := f.(map[string]interface{}) persons := rootMap["persons"].([]interface{}) for _, item := range persons { person := item.(map[string]interface{}) name := person["name"].(string) surname := person["surname"].(string) fmt.Printf("人员:%s %s 的用户名列表:\n", name, surname) // 拿到data数组后继续遍历 dataList := person["data"].([]interface{}) for _, dItem := range dataList { dataMap := dItem.(map[string]interface{}) username := dataMap["username"].(string) fmt.Println("-", username) } }
注意:这种动态断言的方式如果JSON结构和预期不符会直接panic,生产环境建议每个类型断言都加上ok判断,比如:
rootMap, ok := f.(map[string]interface{}) if !ok { // 类型不符的错误处理 }
内容的提问来源于stack exchange,提问作者Lorenzo Romani
相关产品推荐
相关产品推荐

