What's the golang equivalent of converting any JSON to standard dict in Python?

后端 未结 2 917
一生所求
一生所求 2021-02-14 12:49

In Python you can do something like this:

r = requests.get(\"http://wikidata.org/w/api.php\", params=params)
data = r.json()

And now data

相关标签:
2条回答
  • 2021-02-14 13:23

    If you want a dictionary, use the Go type map[string]interface{} (which is a map with string keys and values of any type):

    var data map[string]interface{}
    

    And then you can refer to its elements like:

    data["entities"]
    

    See this example:

    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)
    

    Output:

    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]]
    

    Try it on the Go Playground.

    Notes:

    Basically if your map is multi-level (the map contains another map) like the "innermap" in the above example, when you access the inner map, you can use Type assertion to have it as another map:

    innermap, ok := data["innermap"].(map[string]interface{})
    // If ok, innermap is of type map[string]interface{}
    // and you can refer to its elements.
    
    0 讨论(0)
  • 2021-02-14 13:40

    I prefer to add a type declaration, that way you can add methods to simplify the type assertions:

    package main
    
    import (
       "encoding/json"
       "log"
       "net/http"
       "net/url"
    )
    
    type Map map[string]interface{}
    
    func (m Map) M(s string) Map {
       return m[s].(map[string]interface{})
    }
    
    func (m Map) N(s string) float64 {
       return m[s].(float64)
    }
    
    func main() {
       v := url.Values{}
       v.Set("action", "wbgetentities")
       v.Set("format", "json")
       v.Set("ids", "Q24871")
       resp, e := http.Get("https://www.wikidata.org/w/api.php?" + v.Encode())
       if e != nil {
          log.Fatal(e)
       }
       data := Map{}
       json.NewDecoder(resp.Body).Decode(&data)
       pageid := data.M("entities").M("Q24871").N("pageid")
       println(pageid == 28268)
    }
    

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

    0 讨论(0)
提交回复
热议问题