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"`
}