在Python中,您可以执行以下操作:
r = requests.get("http://wikidata.org/w/api.php", params=params) data = r.json()
现在data是一个dict或哈希表(同样,我不需要预先定义dict的结构),并且我可以通过执行data [“ entities”],data [“ entities”] [“ Q12 “]等
data
我将如何在golang中做到这一点?到目前为止,我有这个:
resp, err := http.Get("http://wikidata.org/w/api.php?"+v.Encode()) if err != nil { // handle error } defer resp.Body.Close() decoder := json.NewDecoder(resp.Body) var data interface{} decodeErr := decoder.Decode(&data) if decodeErr != nil { // handle error } fmt.Println(data["entities"], data["entities"]["Q"+id])
这给了我编译错误: invalid operation: data["entities"] (index of type interface {})
invalid operation: data["entities"] (index of type interface {})
那应该var data是什么类型呢?我是否需要预先为JSON定义结构,还是可以在不修改代码的情况下处理任何JSON文件/流?
var data
如果您要使用字典,请使用Go类型map[string]interface{}(map带有string任何类型的键和值的Go 类型):
map[string]interface{}
map
string
var data map[string]interface{}
然后您可以引用其元素,例如:
data["entities"]
请参阅以下示例:
s := `{"text":"I'm a text.","number":1234,"floats":[1.1,2.2,3.3], "innermap":{"foo":1,"bar":2}}` var data map[string]interface{} err := json.Unmarshal([]byte(s), &data) if err != nil { panic(err) } fmt.Println("text =", data["text"]) fmt.Println("number =", data["number"]) fmt.Println("floats =", data["floats"]) fmt.Println("innermap =", data["innermap"]) innermap, ok := data["innermap"].(map[string]interface{}) if !ok { panic("inner map is not a map!") } fmt.Println("innermap.foo =", innermap["foo"]) fmt.Println("innermap.bar =", innermap["bar"]) fmt.Println("The whole map:", data)
输出:
text = I'm a text. number = 1234 floats = [1.1 2.2 3.3] innermap = map[foo:1 bar:2] innermap.foo = 1 innermap.bar = 2 The whole map: map[text:I'm a text. number:1234 floats:[1.1 2.2 3.3] innermap:map[foo:1 bar:2]]
在Go Playground上尝试一下。
笔记:
基本上,如果您的地图像上面的示例一样是多层的(map包含另一个map)"innermap",则在访问内部地图时,可以使用Type断言将其作为另一个地图:
"innermap"
innermap, ok := data["innermap"].(map[string]interface{}) // If ok, innermap is of type map[string]interface{} // and you can refer to its elements.