有没有一种方法可以通过转换类型在 Go 中解码 JSON?

我正在使用一个 API,如果它为零,它可以返回一个值作为 int,如果它不为零,则作为字符串返回,我想要一个解码器将这两个 JSON 正确解码为结构


{

  "id": 1,

  "rating": 0

}

{

  "id": 2,

  "rating": "2"

}

type User struct {

  Id int64 `json:"id"`

  Rating int64 `json:"rating,string"`

}

因此,它应该尝试将任何 JSON 类型(int、float、string)转换为 struct 中指定的类型,并仅在不可能时引发错误。标准 json.Decoder 不会那样做。


或者也许有一些更可定制的 json 解析库?


桃花长相依
浏览 106回答 3
3回答

PIPIONE

int64您正在尝试从 JSON 字符串解析 an 。您可以使用实现 JSON Unmarshaler 接口的自定义类型来执行此操作。例如type User struct {    Id     int64       `json:"id"`    Rating Int64String `json:"rating"`}type Int64String int64func (i Int64String) MarshalJSON() ([]byte, error) {    return json.Marshal(strconv.FormatInt(int64(i), 10))}func (i *Int64String) UnmarshalJSON(data []byte) error {    var jstring string    err := json.Unmarshal(data, &jstring)    if err != nil {        return err    }    *(*int64)(i), err = strconv.ParseInt(jstring, 0, 64)    return err}操场

POPMUISE

我建议您更改 api,如果那不可能,那么您可以使用接口类型进行评级并在解析期间手动检查类型(int 将返回为 float64):package mainimport (    "fmt"    "encoding/json")type User struct {    Id int `json:"id"`    Rating interface{} `json:"rating"`}func main() {    usersJson := `[{"id": 1, "rating": 0}, {"id": 2,"rating": "2"}]`    var users []User    err := json.Unmarshal([]byte(usersJson), &users)    if err != nil {        fmt.Println("err: ",err)        return    }    for _, u := range users {        switch u.Rating.(type) {        case float64:            fmt.Println("its an float64", u.Rating.(float64))        case string:            fmt.Println("its an string", u.Rating.(string))        }    }}

慕丝7291255

像这样解决:type Int64 struct {        Value int64}func (this *Int64) UnmarshalJSON(bytesValue []byte) error {        stringValue := string(bytesValue)        if len(stringValue) > 2 {                if stringValue[0] == '"' && stringValue[len(stringValue)-1] == '"' {                        stringValue = stringValue[1 : len(stringValue)-1]                }        }        var err error        this.Value, err = strconv.ParseInt(stringValue, 10, 64)        return err}func (this *Int64) MarshalJSON() ([]byte, error) {        return []byte(fmt.Sprintf("%v", this.Value)), nil}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go