为了账号安全,请及时绑定邮箱和手机立即绑定

具有灵活类型的 JSON 解码

具有灵活类型的 JSON 解码

Go
翻阅古今 2021-06-30 03:06:49
我需要以灵活的方式指定用于解码 JSON 数据的类型,这意味着需要在运行时指定类型。考虑这个片段:http : //play.golang.org/p/F-Jy4ufMPzs := `{"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{},而不在编译时指定它。在不预先创建数组的情况下以某种方式可能吗?(退货数量未知)我现在能想到的唯一方法是稍后再次对返回的映射进行编码,并将它们解码为指定的类型,这会产生不必要的处理开销。
查看完整描述

1 回答

?
子衿沉夜

TA贡献1828条经验 获得超3个赞

如果在编译时没有指定它,您仍然需要在某处指定它。


如果在检索 Json 数据之前指定,您可以简单地做一个 switch case,将它解组到您想要的对象。


如果在Json 数据中指定,则可以json.RawMessage在确定适合哪种类型的结构后将“灵活”部分编组到 a 中以进行处理:


package main


import (

    "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

    }

}


查看完整回答
反对 回复 2021-07-05
  • 1 回答
  • 0 关注
  • 151 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信