猿问

具有灵活类型的 JSON 解码

我需要以灵活的方式指定用于解码 JSON 数据的类型,这意味着需要在运行时指定类型。


考虑这个片段:http : //play.golang.org/p/F-Jy4ufMPz


s := `{"b":[{"x":9},{"x":4}]}`


var a struct {

  B []interface{}

}

err := json.Unmarshal([]byte(s), &a)

if err != nil {

  panic(err)

}


fmt.Println(a)

这将产生{[map[x:9] map[x:4]]}. 我想解码为特定(结构)类型的数组而不是[]interface{},而不在编译时指定它。


在不预先创建数组的情况下以某种方式可能吗?(退货数量未知)


我现在能想到的唯一方法是稍后再次对返回的映射进行编码,并将它们解码为指定的类型,这会产生不必要的处理开销。


翻阅古今
浏览 154回答 1
1回答

子衿沉夜

如果在编译时没有指定它,您仍然需要在某处指定它。如果在检索 Json 数据之前指定,您可以简单地做一个 switch case,将它解组到您想要的对象。如果在Json 数据中指定,则可以json.RawMessage在确定适合哪种类型的结构后将“灵活”部分编组到 a 中以进行处理:package mainimport (    "encoding/json"    "fmt")var s = `{"type":"structx", "data":{"x":9,"xstring":"This is structX"}}`type JsonStruct struct {    Type string    Data json.RawMessage}type StructX struct {    X       float64    Xstring string}type StructY struct {    Y bool}func main() {    var a *JsonStruct    err := json.Unmarshal([]byte(s), &a)    if err != nil {        panic(err)    }    switch a.Type {    case "structx":        // We Unmashal the RawMessage part into a StructX        var s *StructX        json.Unmarshal([]byte(a.Data), &s)        if err != nil {            panic(err)        }        fmt.Println(s)    case "structy":        // Do the same but for structY    }}
随时随地看视频慕课网APP

相关分类

Go
我要回答