一尘不染

在Golang中访问类型为map [string] interface {}的嵌套地图

go

因此,我正在尝试解析JSON响应。它可以是多个层次。这是我所做的:

var result map[string]interface{}
json.Unmarshal(apiResponse, &result)

首先,这是正确的方法吗?

可以说响应如下:

{
  "args": {
            "foo": "bar"
          }
}

要访问key foo,我看到一个游乐场正在这样做:

result["args"].(map[string]interface{})["foo"]

在这里,.()表示法是什么?这样对吗?


阅读 1591

收藏
2020-07-02

共1个答案

一尘不染

该符号x.(T)称为类型断言

对于x接口类型和类型T的表达式,主表达式x.(T)断言x不是,nil并且其中存储的值x是类型T

你的例子:

result["args"].(map[string]interface{})["foo"]

这意味着results与key关联的地图的值"args"是类型map[string]interface{}(另一个具有stringkey和任何值的地图)。并且您想要访问与key关联的该映射的元素"foo"

如果您知道输入的JSON格式,那么可以,您必须使用通用map[string]interface{}类型来处理它。如果您知道输入JSON的确切结构,则可以创建一个a
struct来匹配期望的字段,这样做可以将JSON文本解编为您的自定义struct类型的值,例如:

type Point struct {
    Name string
    X, Y int
}

func main() {
    in := `{"Name":"center","X":2,"Y":3}`

    pt := Point{}
    json.Unmarshal([]byte(in), &pt)

    fmt.Printf("Result: %+v", pt)
}

输出:

Result: {Name:center X:2 Y:3}

Go Playground上尝试一下。

建模您的输入

您当前的JSON输入可以使用以下类型建模:

type Data struct {
    Args struct {
        Foo string
    }
}

并访问Foo(在Go
Playground
上尝试

d := Data{}
json.Unmarshal([]byte(in), &d)
fmt.Println("Foo:", d.Args.Foo)
2020-07-02