2 回答
TA贡献1794条经验 获得超8个赞
由于 2 种值类型发生冲突(一种是结构,另一种是结构的一部分),因此即使使用捕获所有解决方案(如 ),将其封装到单个类型中也会变得很混乱。interface{}
最简单的解决方案是呈现两种不同的类型并封送到其中任何一个,以查看哪个“有效”:
func unmarsh(body []byte) (*type1, *type2, error) {
var (
t1 type1
t2 type2
)
err := json.Unmarshal(body, &t1)
if err == nil {
return &t1, nil, nil
}
err = json.Unmarshal(body, &t2)
if err == nil {
return nil, &t2, nil
}
return nil, nil, err
}
在您的示例中,两种类型将是:
type type1 struct {
Application struct {
Instance []struct {
InstanceID string `json:"instanceId"`
} `json:"instance"`
} `json:"application"`
}
type type2 struct {
Application struct {
Instance struct {
InstanceID string `json:"instanceId"`
} `json:"instance"`
} `json:"application"`
}
工作示例:https://play.golang.org/p/Kma32gWfghb
TA贡献1785条经验 获得超8个赞
一个更干净的解决方案是自定义的拆包器:
type Instances []Instance
func (i *Instances) UnmarshalJSON(in []byte) error {
if len(in)>0 && in[0]=='[' {
var a []Instance
if err:=json.Unmarshal(in,&a); err!=nil {
return err
}
*i=a
return nil
}
var s Instance
if err:=json.Unmarshal(in,&s) ; err!=nil {
return err
}
*i=[]Instance{s}
return nil
}
这会将对象解封为 1 的切片。
@mkopriva提供了更紧凑的解决方案:
func (i *Instances) UnmarshalJSON(in []byte) error {
if len(in) > 0 && in[0] == '[' {
return json.Unmarshal(in, (*[]Instance)(i))
}
*i = Instances{{}}
return json.Unmarshal(in, &(*i)[0])
}
- 2 回答
- 0 关注
- 62 浏览
添加回答
举报