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

使用 json.RawMessage 将 json 解组为结构

使用 json.RawMessage 将 json 解组为结构

Go
牛魔王的故事 2022-03-07 16:00:29
我需要解组可能具有以下格式的 json 对象:-Format1:    {    "contactType": 2,    "value": "0123456789"    }Format2:    {    "contactType": "MobileNumber",    "value": "0123456789"    }我用于解组的结构是:-    type Contact struct {    ContactType int    `json:"contactType"`     Value       string `json:"value"`    }但这仅适用于格式 1。我不想更改 ContactType 的数据类型,但我也想适应第二种格式。我听说过 json.RawMarshal 并尝试使用它。    type Contact struct {        ContactType        int        Value       string          `json:"value"`        Type json.RawMessage `json:"contactType"    }    type StringContact struct {    Type string `json:"contactType"`    }    type IntContact struct {    Type int `json:"contactType"`    } 这完成了解组,但我无法设置取决于 json.RawMessage 类型的 ContactType 变量。如何为我的结构建模以便解决这个问题?
查看完整描述

1 回答

?
慕田峪7331174

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

您需要自己进行解组。有一篇非常好的文章展示了如何使用 json.RawMessage 权利和许多其他解决这个问题的方法,比如使用接口、RawMessage、实现你自己的解组和解码函数等。


您可以在此处找到文章:Attila Oláh 在 GO 中的 JSON 解码 注意:Attila 在他的代码示例中犯了一些错误。


我冒昧地整理了一个工作示例(使用 Attila 的一些代码),它使用 RawMessage 来延迟解组,以便我们可以在我们自己的 Decode func 版本上进行。


链接到 GOLANG 游乐场


package main


import (

    "fmt"

    "encoding/json"

    "io"

)


type Record struct {

    AuthorRaw json.RawMessage `json:"author"`

    Title     string          `json:"title"`

    URL       string          `json:"url"`


    Author Author

}


type Author struct {

    ID    uint64 `json:"id"`

    Email string `json:"email"`

}


func Decode(r io.Reader) (x *Record, err error) {

    x = new(Record)

    if err = json.NewDecoder(r).Decode(x); err != nil {

        return

    }

    if err = json.Unmarshal(x.AuthorRaw, &x.Author); err == nil {

        return

    }

    var s string

    if err = json.Unmarshal(x.AuthorRaw, &s); err == nil {

        x.Author.Email = s

        return

    }

    var n uint64

    if err = json.Unmarshal(x.AuthorRaw, &n); err == nil {

        x.Author.ID = n

    }

    return

}


func main() {


    byt_1 := []byte(`{"author": 2,"title": "some things","url": "https://stackoverflow.com"}`)


    byt_2 := []byte(`{"author": "Mad Scientist","title": "some things","url": "https://stackoverflow.com"}`)


    var dat Record


    if err := json.Unmarshal(byt_1, &dat); err != nil {

            panic(err)

    }

    fmt.Printf("%#s\r\n", dat)


    if err := json.Unmarshal(byt_2, &dat); err != nil {

            panic(err)

    }

    fmt.Printf("%#s\r\n", dat)

}

希望这可以帮助。


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

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号