猿问

Golang 解组 json 映射和数组

在阅读了JSON 和 Go 之后,我确实了解了在 Go 中解码 json 的基础知识。但是,存在这个问题,输入 json 有时可以是地图,有时是地图数组。


考虑以下问题:


package main


import (

    "encoding/json"

    "fmt"

)


func main() {

    b := []byte(`[{"email":"example@test.com"}]`)

    c := []byte(`{"email":"example@test.com"}`)


    var m interface{}


    json.Unmarshal(b, &m)

    switch v := m.(type) {

    case []interface{}:

        fmt.Println("this is b", v)

    default:

        fmt.Println("No type found")

    }


    json.Unmarshal(c, &m)

    switch v := m.(type) {

    case map[string]interface{}:

        fmt.Println("this is c", v)

    default:

        fmt.Println("No type found")

    }


}

现在,我如何获得价值email:example@test.com在这两种情况下(b& c)

问题:

  1. 如果 json 是一个数组,我想遍历每个并打印电子邮件。

  2. 如果json是地图,我想直接打印email

播放:http : //play.golang.org/p/UPoFxorqWl


慕少森
浏览 133回答 3
3回答

白猪掌柜的

根据我的经验,使用 interface{} 处理 json 解码可能会导致一些奇怪的问题,我倾向于避免它。尽管有一些方法可以使用反射包来实现它。这是基于您的原始解决方案的问题解决方案,希望对您有所帮助。package mainimport (    "encoding/json"    "fmt")type Item struct {    Email string `json:email`}func main() {    b := []byte(`[{"email":"example_in_array@test.com"}]`)    //b := []byte(`{"email":"example@test.com"}`)    var m = &Item{}    var ms = []*Item{}    err := json.Unmarshal(b, &m)    if err != nil {        err = json.Unmarshal(b, &ms)        if err != nil {            panic(err)        }        for _, m := range ms {            fmt.Println(m.Email)        }    } else {        fmt.Println(m.Email)    }}

蓝山帝景

这是你想要的吗?http://play.golang.org/p/8yrirlUAnppackage mainimport (    "encoding/json"    "fmt")func main() {    b := []byte(`[{"email":"example@test.com"}]`)    c := []byte(`{"email":"example@test.com"}`)    var m interface{}    json.Unmarshal(b, &m)    switch v := m.(type) {    case []interface{}:        for _, x := range v {            fmt.Println("this is b", x.(map[string]interface{})["email"])        }    default:        fmt.Println("No type found")    }    json.Unmarshal(c, &m)    switch v := m.(type) {    case map[string]interface{}:        fmt.Println("this is c", v["email"])    default:        fmt.Println("No type found")    }}编辑:错过了循环部分,添加了它。

胡说叔叔

这不是最惯用的方法,但另一种方法是尝试将其编组为您想要的类型。这里的优点是没有超出需要的额外反射。http://play.golang.org/p/dV5qCu3tKkpackage mainimport (    "encoding/json"    "fmt")func main() {    fmt.Println(extract([]byte(`[{"email":"example@test.com"}]`)))    fmt.Println(extract([]byte(`{"email":"example@test.com"}`)))}func extract(b []byte) string {    var m map[string]string    err := json.Unmarshal(b, &m)    if err == nil {        return m["email"]    }    var nested []map[string]string    err = json.Unmarshal(b, &nested)    if err == nil {        for _, m := range nested {            return m["email"]        }    }    return ""}
随时随地看视频慕课网APP

相关分类

Go
我要回答