编码/解码JSON golang中的多类型字段 [英] Encoding/Decoding multi-type fields in JSON golang

查看:134
本文介绍了编码/解码JSON golang中的多类型字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个结构,其中一个字段可以保存一些特殊类型的数据,例如intstringCustomType.我想将此结构从JSON解码/编码.我们如何在go/golang中实现这一目标?

I am trying to create a struct where a field can hold data of a few particular types, say int, string and a CustomType. I want to decode/encode this struct to/from JSON. How can we achieve this in go/golang?

例如,我具有以下定义的结构:

For example, I have a struct for the following definition:

type MyData struct {
  Name  string                                    `json:"name"`
  Value int32                                     `json:"value"`
  Param <can be either int, string or CustomType> `json:"param"`
}

CustomType的位置

type CustomType struct {
  Custom bool `json:"custom"`
}

假设我需要将以下JSON解组到上述结构MyData:

Let's say I need to unmarshal the following JSONs to the above struct MyData:

{
  "name": "Hello",
  "value": 32
  "param": "World"
}

还有一个:

{
  "name": "Hello",
  "value": 32
  "param": 100
}

这也是:

{
  "name": "Hello",
  "value": 32
  "param": {
     "custom": true
  }
}

我该如何实现?

我可以在MyData上定义自己的MarshalJSONUnmarshalJSON并实现吗?

Can I define my own MarshalJSON and UnmarshalJSON on MyData and achieve this?

或者是否可以定义自定义类型,例如IntOrStringOrCustom并将MyData定义为

Or is there a way of defining a custom type, say IntOrStringOrCustom and define MyData as

type MyData struct {
  Name  string              `json:"name"`
  Value int32               `json:"value"`
  Param IntOrStringOrCustom `json:"param"`
}

,然后在IntOrStringOrCustom上定义MarshalJSONUnmarshalJSON?

我也看过json.RawMessage.我们可以在这里以某种方式使用它吗?

I have also seen json.RawMessage. Can we use it somehow here?

使用interface{}的问题是,我将不得不在尝试使用此数据的任何地方编写编码/解码逻辑.还是用interface{}做到这一点的优雅方法?

Issue with using interface{} is that I will have to write the encoding/decoding logic everywhere, where I am trying to use this data. Or is there an elegant way of doing this with interface{}?

推荐答案

已更新. interface会自动很好地编码和解码为JSON.如果希望控制类型,则可以添加特殊的UnmarshalJSON并在其中进行检查:

UPDATED. interface gets encoded and decoded to JSON well automatically. If you wish to control types, you may add special UnmarshalJSON and perform checks in it:

type TheParam interface{}

type MyData struct {
    Name  string   `json:"name"`
    Value int32    `json:"value"`
    Param TheParam `json:"param"`
}

type myData MyData

func (m *MyData) UnmarshalJSON(b []byte) error {
    var mm myData
    if err := json.Unmarshal(b, &mm); err != nil {
        return err
    }
    switch mm.Param.(type) {
    case float64, string, map[string]interface{}:
        *m = MyData(mm)
        return nil
    default:
        return InvalidFieldTypeError{value: mm.Param}
    }
    return nil
}

类型InvalidFieldTypeError可能很方便返回此类错误,并且可以将其定义为:

Type InvalidFieldTypeError may be convenient to return such class of errors and can be defined as:

type InvalidFieldTypeError struct {
    value interface{}
}

func (e InvalidFieldTypeError) Error() string {
    return fmt.Sprintf("Field type '%T' is not valid for MyData", e.value)
}

整个示例: https://play.golang.org/p/MuW6gwSAKi

我也想推荐这篇文章 https://attilaolah.eu/2013/11/29/json-decoding-in-go/

这篇关于编码/解码JSON golang中的多类型字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆