我在寻找一种不涉及引入一个额外的“通用”字段的溶液等Value
,Data
等这将是该变种领域的占位符。
我有一个JSON规范,它描述了几个大型结构,这些结构主要包含简单的值,但偶尔也有一个结构本身的值,其动态类型取决于某个字段的值。
例如,这两个JSON文档都应解组到相同的Go结构:
{
"some_data": "foo",
"dynamic_field": { "type": "A", "name": "Johnny" },
"other_data": "bar"
}
和
{
"some_data": "foo",
"dynamic_field": { "type": "B", "address": "Somewhere" },
"other_data": "bar"
}
JSON结构已设置,我无法更改。
Go结构必须如下所示:
type BigStruct struct {
SomeData string `json:"some_data"`
DynamicField Something `json:"dynamic_field"`
OtherData string `json:"other_data"`
}
问题是如何实际执行操作以及该Something
类型应为哪种类型。
我首先使其成为一个接口:
type Something interface {
GetType() string
}
并具有以下几种结构和功能:
type BaseDynamicType struct {
Type string `json:"type"`
}
type DynamicTypeA struct {
BaseDynamicType
Name string `json:"name"`
}
type DynamicTypeB struct {
BaseDynamicType
Address string `json:"address"`
}
func (d *BaseDynamicType) GetType() string {
return d.Type
}
原因是,当我获得的实例时BigStruct
,我可以这样做:
switch big.DynamicField.GetType() {
case "A": // do something with big.DynamicField cast to DynamicTypeA
case "B": // do something with big.DynamicField cast to DynamicTypeB
}
但是,然后我陷入了困境-
这种安排如何配合UnmarshalJSON
?我认为BigStruct
应该实施UnmarshalJSON
将以某种方式检查的Type
字段,dynamic_field
然后基于该字段,使DynamicField
a
DynamicTypeA
或DynamicTypeB
。
但是如何?由于递归可能不起作用的一种方法是:
DynamicField
为json:"-"
UnmarshalJSON
BigStructmap[string]interface{}
在BigStruct
的UnmarshalJSON
,dynamic_field
地图中的值,手动构建DynamicTypeA
或DynamicTypeB
BigStruct
DynamicField
用手动创建的值修正…但是当我尝试将数据解组到a时将导致在第五步中无限递归,BigStruct
后者将调用UnmarshalJSON
当前正在执行的相同函数。
type BigStruct struct {
SomeData string `json:"some_data"`
DynamicField DynamicType `json:"dynamic_field"`
OtherData string `json:"other_data"`
}
type DynamicType struct {
Value interface{}
}
func (d *DynamicType) UnmarshalJSON(data []byte) error {
var typ struct {
Type string `json:"type"`
}
if err := json.Unmarshal(data, &typ); err != nil {
return err
}
switch typ.Type {
case "A":
d.Value = new(TypeA)
case "B":
d.Value = new(TypeB)
}
return json.Unmarshal(data, d.Value)
}
type TypeA struct {
Name string `json:"name"`
}
type TypeB struct {
Address string `json:"address"`
}
https://play.golang.com/p/oKMKQTdzp7s
如果您不想或不能更改DynamicField的类型,则可以将UnmarshalJSON方法放在BigStruct上,并声明一个临时类型以避免递归。
func (b *BigStruct) UnmarshalJSON(data []byte) error {
var typ struct {
DF struct {
Type string `json:"type"`
} `json:"dynamic_field"`
}
if err := json.Unmarshal(data, &typ); err != nil {
return err
}
switch typ.DF.Type {
case "A":
b.DynamicField = new(DynamicTypeA)
case "B":
b.DynamicField = new(DynamicTypeB)
}
type tmp BigStruct // avoids infinite recursion
return json.Unmarshal(data, (*tmp)(b))
}
https://play.golang.com/p/at5Okp3VU2u
这是我的密码 抱歉,如果我的代码一团糟。
我试着写一个小函数,它接受两个列表,并根据另一个列表的元素对一个进行排序。所以类似于: 将产生一个排序列表。 然而,可能是一个不同的列表,比如整数、浮点数或其他列表。理想情况下,我希望我的程序能够获取我抛出的任何列表,根据
我有一个应用程序,需要在配置文件中存储一些秘密密码,如数据库和ftp密码/详细信息。我环顾四周,发现了许多使用AES的加密/解密解决方案,但我似乎不知道如何在不改变密钥的情况下使其工作。这意味着我可以加密和解密(使用相同的秘密密钥),但在重启等过程中保持持久性。我似乎无法让秘密钥匙保持不变。下面的示例显示了我的工作方法: 到目前为止还不错。然而,如果我运行它一次,我可能会得到'2Vhht/L80U
本文向大家介绍基于私钥加密公钥解密的RSA算法C#实现方法,包括了基于私钥加密公钥解密的RSA算法C#实现方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了基于私钥加密公钥解密的RSA算法C#实现方法,是一种应用十分广泛的算法。分享给大家供大家参考之用。具体方法如下: 一、概述 RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。 RSA是被研究得最广泛的公钥算法,从提出
我在我的项目中使用React钩子,需要尝试解决如何在状态值发生变化时动态地将类添加到
我有一个如下所示的数组(这是一个$data变量的打印) 我想做的是在数组中循环,将具有相同prod_键的项目组合成一个项目,并更新总数、数量和重量,这样上面的示例应该如下所示: