在Golang中访问Type map [string] interface {}的嵌套Map

Sre*_*nan 12 json dictionary interface go

所以我正在尝试解析JSON响应.它可以是多层次的.这就是我做的:

var result map[string]interface{}
json.Unmarshal(apiResponse, &result)
Run Code Online (Sandbox Code Playgroud)

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

让我们说回应如下:

{
  "args": {
            "foo": "bar"
          }
}
Run Code Online (Sandbox Code Playgroud)

为了访问密钥foo,我看到一个游乐场这样做:

result["args"].(map[string]interface{})["foo"]
Run Code Online (Sandbox Code Playgroud)

在这里,.()符号是什么?它是否正确?

icz*_*cza 21

该表示法x.(T)称为类型断言.

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

你的例子:

result["args"].(map[string]interface{})["foo"]
Run Code Online (Sandbox Code Playgroud)

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

如果您知道输入JSON格式,那么是的,您必须使用泛型map[string]interface{}类型来处理它.如果您知道输入JSON的确切结构,则可以创建一个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)
}
Run Code Online (Sandbox Code Playgroud)

输出:

Result: {Name:center X:2 Y:3}
Run Code Online (Sandbox Code Playgroud)

Go Playground尝试一下.

建模您的输入

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

type Data struct {
    Args struct {
        Foo string
    }
}
Run Code Online (Sandbox Code Playgroud)

访问Foo(在Go Playground上试试):

d := Data{}
json.Unmarshal([]byte(in), &d)
fmt.Println("Foo:", d.Args.Foo)
Run Code Online (Sandbox Code Playgroud)

  • @SreejithRamakrishnan是的,`stirng(foo)`和`foo。(string)`之间是有区别的。第一个是_conversion_,第二个是_type assertion_。类型声明只能在_interface types _(“ interface {}”是一个合格的空接口)上使用,有关转换规则,请阅读规范:[Conversions](http://golang.org/ref/spec#Conversions )。如果您遇到这种情况,则不能仅使用转换类型声明。 (2认同)

小智 12

struct是最好的选择,但如果您坚持,您可以为映射添加类型声明,然后您可以添加方法来帮助进行类型断言:

package main
import "encoding/json"

type dict map[string]interface{}

func (d dict) d(k string) dict {
   return d[k].(map[string]interface{})
}

func (d dict) s(k string) string {
   return d[k].(string)
}

func main() {
   apiResponse := []byte(`{"args": {"foo": "bar"}}`)
   var result dict
   json.Unmarshal(apiResponse, &result)
   foo := result.d("args").s("foo")
   println(foo == "bar")
}
Run Code Online (Sandbox Code Playgroud)

https://golang.org/ref/spec#Type_declarations