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

Rup*_*gar 5 json go unmarshalling

我需要解组 json 对象,它可能具有以下格式:

格式1:

{
    "contactType": 2,
    "value": "0123456789"
}
Run Code Online (Sandbox Code Playgroud)

格式2:

{
    "contactType": "MobileNumber",
    "value": "0123456789"
}
Run Code Online (Sandbox Code Playgroud)

我用于解组的结构是:-

type Contact struct {
    ContactType int    `json:"contactType"` 
    Value       string `json:"value"`
}
Run Code Online (Sandbox Code Playgroud)

但这仅适用于格式 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"`
} 
Run Code Online (Sandbox Code Playgroud)

这完成了解组,但我无法设置ContactType取决于 的类型的变量json.RawMessage。如何对我的结构进行建模才能解决这个问题?

dmp*_*lla 3

您需要自己进行解组。有一篇非常好的文章展示了如何正确使用 json.RawMessage 以及针对此问题的许多其他解决方案,例如使用接口、RawMessage、实现您自己的解组和解码函数等。

\n\n

您可以在这里找到这篇文章: Attila Ol\xc3\xa1h \n的 GO 中的 JSON 解码注意:Attila 在他的代码示例中犯了一些错误。

\n\n

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

\n\n

链接到 GOLANG 游乐场

\n\n
package main\n\nimport (\n    "fmt"\n    "encoding/json"\n    "io"\n)\n\ntype Record struct {\n    AuthorRaw json.RawMessage `json:"author"`\n    Title     string          `json:"title"`\n    URL       string          `json:"url"`\n\n    Author Author\n}\n\ntype Author struct {\n    ID    uint64 `json:"id"`\n    Email string `json:"email"`\n}\n\nfunc Decode(r io.Reader) (x *Record, err error) {\n    x = new(Record)\n    if err = json.NewDecoder(r).Decode(x); err != nil {\n        return\n    }\n    if err = json.Unmarshal(x.AuthorRaw, &x.Author); err == nil {\n        return\n    }\n    var s string\n    if err = json.Unmarshal(x.AuthorRaw, &s); err == nil {\n        x.Author.Email = s\n        return\n    }\n    var n uint64\n    if err = json.Unmarshal(x.AuthorRaw, &n); err == nil {\n        x.Author.ID = n\n    }\n    return\n}\n\nfunc main() {\n\n    byt_1 := []byte(`{"author": 2,"title": "some things","url": "https://stackoverflow.com"}`)\n\n    byt_2 := []byte(`{"author": "Mad Scientist","title": "some things","url": "https://stackoverflow.com"}`)\n\n    var dat Record\n\n    if err := json.Unmarshal(byt_1, &dat); err != nil {\n            panic(err)\n    }\n    fmt.Printf("%#s\\r\\n", dat)\n\n    if err := json.Unmarshal(byt_2, &dat); err != nil {\n            panic(err)\n    }\n    fmt.Printf("%#s\\r\\n", dat)\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

希望这可以帮助。

\n