简体   繁体   English

如何使用未知字段类型将数据解组到 JSON

[英]How to Unmarshall data to JSON with unknown field types

I have these 'structures'我有这些“结构”

type Results struct {
    Gender string `json:"gender"`
    Name   struct {
        First string `json:"first"`
        Last  string `json:"last"`
    } `json:"name"`
    Location struct {
        Postcode int `json:"postcode"`
    }
    Registered struct {
        Date string `json:"date"`
    } `json:"registered"`
}

type Info struct {
    Seed    string `json:"seed"`
    Results int64  `json:"results"`
    Page    int64  `json:"page"`
    Version string `json:"version"`
}

type Response struct {
    Results []Results `json:"results"`
    Info    Info      `json:"info"`
}

I' making a request to an external API and converting data to a JSON view.我向外部 API 发出请求并将数据转换为 JSON 视图。 I know in advance the types of all fields, but the problem occurs with the 'postcode' field.我事先知道所有字段的类型,但是“邮政编码”字段出现问题。 I'm getting different types of values, which is why I get a JSON decoding error.我得到不同类型的值,这就是为什么我得到 JSON 解码错误。 In this case, 'postcode' can be one of three variants:在这种情况下,“邮政编码”可以是以下三种变体之一:

  1. string ~ "13353"字符串〜“13353”
  2. int ~ 13353整数 ~ 13353
  3. string ~ "13353postcode"字符串〜“13353邮政编码”

Changing the postcode type from string to json.Number solved the problem.postcode类型从string更改为json.Number解决了问题。 But this solution does not satisfy the third "option".但是这个解决方案不满足第三个“选项”。

I know I can try to create a custom type and implement an interface on it.我知道我可以尝试创建自定义类型并在其上实现接口。 Seems to me the best solution using json.RawMessage .在我看来,使用json.RawMessage的最佳解决方案。 It's the first I've faced this problem, So I'm still looking for an implementation of a solution to this and reading the documentation.这是我第一次遇到这个问题,所以我仍在寻找解决方案的实现并阅读文档。

What's the best way solution in this case?在这种情况下,最好的解决方案是什么? Thanks in advance.提前致谢。

Declare a custom string type and have it implement the json.Unmarshaler interface.声明一个自定义字符串类型并让它实现json.Unmarshaler接口。

For example, you could do this:例如,您可以这样做:

type PostCodeString string

// UnmarshalJSON implements the json.Unmarshaler interface.
func (s *PostCodeString) UnmarshalJSON(data []byte) error {
    if data[0] != '"' { // not string, so probably int, make it a string by wrapping it in double quotes
        data = []byte(`"`+string(data)+`"`)
    }

    // unmarshal as plain string
    return json.Unmarshal(data, (*string)(s))
}

https://play.golang.org/p/pp-zNNWY38M https://play.golang.org/p/pp-zNNWY38M

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM