Golang:访问嵌套映射中的未知值[string]接口{}
Golang: Accessing Unknown Values in Nested map[string]interface{}
长期聆听,第一次来电!
我是 Go 的初学者,但有几年的 Python 经验。所以,请原谅我的无知
所以,我正在尝试将来自 Web 服务器的多级 json 响应解析为 map[string]interface{} 类型。
示例:
func GetResponse() (statusCode int, responseData map[string]interface{}){
host := "https://somebogusurl.com/fake/json/data"
request, err := http.NewRequest("GET", host, nil)
if err != nil {
panic(err)
}
client := http.Client{}
response, err := client.Do(request)
if err != nil {
panic(err)
}
defer response.Body.Close()
data, _ := ioutil.ReadAll(response.Body)
json.Unmarshal([]byte(data), &responseData)
return response.StatusCode, responseData
}
func main() {
statusCode, data := GetResponse()
fmt.Println(data["foo"].(map[string]interface{})["bar"])
}
如您所见,我正在尝试访问返回的新地图中的嵌套值。但是,我收到以下错误:
panic: interface conversion: interface {} is []interface {}, not map[string]interface {}
我相信我正在尝试访问接口中的嵌套数据,而不是基于错误的映射[string]接口。知道我如何访问嵌套数据吗?
问题是你的对象可能是这样的:
{
"x":[1,2,3]
}
并且当 json.Unmarshal 被调用时,它会 return 一个类似于这个的地图:
map[string]interface {}{"x":[]interface {}{1, 2, 3}}
当 json 键包含一个数组时,它被转换为一个 []interface{},因为数组可以包含任何类型的值
要获得您需要的地图,您的对象的形状应类似于:
{
"x":{
"y":"z"
}
}
解组后你会得到类似
的东西
map[string]interface {}{"x":map[string]interface {}{"y":"z"}}
如果您事先不知道对象内部的数据类型,则必须使用反射来检查值并避免错误的类型断言或不正确的行为。另一种可能性是通过类型断言检查第二个值 returned 或使用类型开关。例如:
//With type assertion
if val,ok:=m["key"].(map[string]interface{});ok{
//val is map[string]interface{} do something with inner dict
val["subkey"]
}
//With type switch
switch val := m["key"].(type) {
case []interface{}:
//access values by index
val[0]...
case map[string]interface{}:
//do something with inner dict
val["subkey"]...
}
}
你可以用 user struct 替换 map[string]interface{} .
假设您有以下 JSON
{
"id": -26798974.698663697,
"name": "et anim in consectetur",
"department_id": 1113574.4678084403,
"department_name": "aut",
"department_path": "in",
"ctime": "tempor culpa",
"utime": "culpa ipsum officia d",
"project_type": -63043086.205600575,
"project_type_label": "",
"manager_name": "aliquip incididunt",
"manager_id": 33403365.665011227,
"members": [
{
"id": -71868040.04283473,
"name": "ullamco",
"username": "dolor sed enim velit",
"phone": "in",
"email": "quis",
"role": "et volu",
"uemail": "in",
"uphone": "id ut Duis"
},
{
"id": -66953595.48747035,
"name": "non velit",
"username": "dolore irure elit reprehenderit",
"phone": "in dolor voluptate enim",
"email": "ipsum minim occaecat sunt",
"role": "amet occaecat incididunt nisi",
"uemail": "ea",
"uphone": "adipisicing in sint"
},
{
"id": 55743250.12837607,
"name": "nisi dolore minim",
"username": "sit Ut id proident deserunt",
"phone": "dolore nulla",
"email": "sunt id ex ea exercitation",
"role": "reprehenderit commodo laborum enim consectetur",
"uemail": "in nulla ullamco ea",
"uphone": "eu"
},
{
"id": -29129221.093446136,
"name": "deserunt officia tempor Duis",
"username": "cupidatat ut aute",
"phone": "ex aute",
"email": "in",
"role": "mollit",
"uemail": "minim",
"uphone": "proident et qui nulla ullamco"
}
]
}
你可以使用下面的结构来解析json
type Autogenerated struct {
ID float64 `json:"id"`
Name string `json:"name"`
DepartmentID float64 `json:"department_id"`
DepartmentName string `json:"department_name"`
DepartmentPath string `json:"department_path"`
Ctime string `json:"ctime"`
Utime string `json:"utime"`
ProjectType float64 `json:"project_type"`
ProjectTypeLabel string `json:"project_type_label"`
ManagerName string `json:"manager_name"`
ManagerID float64 `json:"manager_id"`
Members []struct {
ID float64 `json:"id"`
Name string `json:"name"`
Username string `json:"username"`
Phone string `json:"phone"`
Email string `json:"email"`
Role string `json:"role"`
Uemail string `json:"uemail"`
Uphone string `json:"uphone"`
} `json:"members"`
}
长期聆听,第一次来电!
我是 Go 的初学者,但有几年的 Python 经验。所以,请原谅我的无知
所以,我正在尝试将来自 Web 服务器的多级 json 响应解析为 map[string]interface{} 类型。
示例:
func GetResponse() (statusCode int, responseData map[string]interface{}){
host := "https://somebogusurl.com/fake/json/data"
request, err := http.NewRequest("GET", host, nil)
if err != nil {
panic(err)
}
client := http.Client{}
response, err := client.Do(request)
if err != nil {
panic(err)
}
defer response.Body.Close()
data, _ := ioutil.ReadAll(response.Body)
json.Unmarshal([]byte(data), &responseData)
return response.StatusCode, responseData
}
func main() {
statusCode, data := GetResponse()
fmt.Println(data["foo"].(map[string]interface{})["bar"])
}
如您所见,我正在尝试访问返回的新地图中的嵌套值。但是,我收到以下错误:
panic: interface conversion: interface {} is []interface {}, not map[string]interface {}
我相信我正在尝试访问接口中的嵌套数据,而不是基于错误的映射[string]接口。知道我如何访问嵌套数据吗?
问题是你的对象可能是这样的:
{
"x":[1,2,3]
}
并且当 json.Unmarshal 被调用时,它会 return 一个类似于这个的地图:
map[string]interface {}{"x":[]interface {}{1, 2, 3}}
当 json 键包含一个数组时,它被转换为一个 []interface{},因为数组可以包含任何类型的值
要获得您需要的地图,您的对象的形状应类似于:
{
"x":{
"y":"z"
}
}
解组后你会得到类似
的东西map[string]interface {}{"x":map[string]interface {}{"y":"z"}}
如果您事先不知道对象内部的数据类型,则必须使用反射来检查值并避免错误的类型断言或不正确的行为。另一种可能性是通过类型断言检查第二个值 returned 或使用类型开关。例如:
//With type assertion
if val,ok:=m["key"].(map[string]interface{});ok{
//val is map[string]interface{} do something with inner dict
val["subkey"]
}
//With type switch
switch val := m["key"].(type) {
case []interface{}:
//access values by index
val[0]...
case map[string]interface{}:
//do something with inner dict
val["subkey"]...
}
}
你可以用 user struct 替换 map[string]interface{} .
假设您有以下 JSON
{
"id": -26798974.698663697,
"name": "et anim in consectetur",
"department_id": 1113574.4678084403,
"department_name": "aut",
"department_path": "in",
"ctime": "tempor culpa",
"utime": "culpa ipsum officia d",
"project_type": -63043086.205600575,
"project_type_label": "",
"manager_name": "aliquip incididunt",
"manager_id": 33403365.665011227,
"members": [
{
"id": -71868040.04283473,
"name": "ullamco",
"username": "dolor sed enim velit",
"phone": "in",
"email": "quis",
"role": "et volu",
"uemail": "in",
"uphone": "id ut Duis"
},
{
"id": -66953595.48747035,
"name": "non velit",
"username": "dolore irure elit reprehenderit",
"phone": "in dolor voluptate enim",
"email": "ipsum minim occaecat sunt",
"role": "amet occaecat incididunt nisi",
"uemail": "ea",
"uphone": "adipisicing in sint"
},
{
"id": 55743250.12837607,
"name": "nisi dolore minim",
"username": "sit Ut id proident deserunt",
"phone": "dolore nulla",
"email": "sunt id ex ea exercitation",
"role": "reprehenderit commodo laborum enim consectetur",
"uemail": "in nulla ullamco ea",
"uphone": "eu"
},
{
"id": -29129221.093446136,
"name": "deserunt officia tempor Duis",
"username": "cupidatat ut aute",
"phone": "ex aute",
"email": "in",
"role": "mollit",
"uemail": "minim",
"uphone": "proident et qui nulla ullamco"
}
]
}
你可以使用下面的结构来解析json
type Autogenerated struct {
ID float64 `json:"id"`
Name string `json:"name"`
DepartmentID float64 `json:"department_id"`
DepartmentName string `json:"department_name"`
DepartmentPath string `json:"department_path"`
Ctime string `json:"ctime"`
Utime string `json:"utime"`
ProjectType float64 `json:"project_type"`
ProjectTypeLabel string `json:"project_type_label"`
ManagerName string `json:"manager_name"`
ManagerID float64 `json:"manager_id"`
Members []struct {
ID float64 `json:"id"`
Name string `json:"name"`
Username string `json:"username"`
Phone string `json:"phone"`
Email string `json:"email"`
Role string `json:"role"`
Uemail string `json:"uemail"`
Uphone string `json:"uphone"`
} `json:"members"`
}