所以我试图解析JSON响应。它可以是多层次的。这就是我所做的:
var result map[string]interface{}
json.Unmarshal(apiResponse, &result)
首先,这是正确的方法吗?
让我们说回应如下:
{
"args": {
"foo": "bar"
}
}
要访问密钥foo
,我看到playground执行此操作:
result["args"].(map[string]interface{})["foo"]
这里,.()
符号是什么?这是对的吗?
答案 0 :(得分:18)
符号x.(T)
称为Type Assertion。
对于接口类型的表达式
x
和类型T
,主表达式x.(T)
断言x
不是nil
并且存储的值x
中的T
类型。
你的例子:
result["args"].(map[string]interface{})["foo"]
这意味着与关键字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)
}
输出:
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)
答案 1 :(得分:1)
我更喜欢为 Map 添加类型声明,然后您可以添加方法来帮助 使用类型断言:
package main
import "encoding/json"
type dict map[string]interface{}
func (d dict) D(s string) dict {
return d[s].(map[string]interface{})
}
func (d dict) S(s string) string {
return d[s].(string)
}
func main() {
apiResponse := []byte(`{"args": {"foo": "bar"}}`)
var result dict
json.Unmarshal(apiResponse, &result)
foo := result.D("args").S("foo")
println(foo == "bar")
}