Go语言本身是强类型的,处理一些弱类型语言的json时会遇到相同的字段,类型是不固定的这种情况,字段定义为interface{}挨个去解析可以解决这个问题,但随着数据量大了之后,嵌套格式越深,这将是一个大坑
[
{
"test": 1
},
{
"test": true
}
]
在上面这段json里,type字段的值有传int类型的,有传bool类型的。
如果只是判断是与否,会定义为:
type Feature struct {
Test bool `json:"test"`
}
假定现在就用这种结构体去解析Json:
const featuresText = `
[
{
"test": 1
},
{
"test": true
}
]`
func main() {
var features []Feature
e := json.Unmarshal([]byte(featuresText), &features)
log.Printf("features: %#v,\nerror: %v", features, e)
}
会有错误信息输出:
features: []example.Feature{example.Feature{Test:false}, example.Feature{Test:true}},
error: json: cannot unmarshal number into Go struct field Feature.test of type bool
我们可以通过实现自定义Json解析来解决这个问题:
type Feature struct {
Test bool `json:"test"`
}
// 定义一个字段类型为interface类型的Feature,再使用switch type来解决类型的问题
type TempFeature struct {
Test interface{} `json:"test"` // 数字或布尔类型
}
// 自定义Feature Json解码
func (f *Feature) UnmarshalJSON(b []byte) (e error) {
var temp TempFeature
e = json.Unmarshal(b, &temp)
if e != nil {
return
}
// 判断类型
switch v := temp.Test.(type) {
case bool:
f.Test = v
case float64:
f.Test = v > 0
}
return nil
}
执行之前的main方法,输出结果:
[]example.Feature{example.Feature{Test:true}, example.Feature{Test:true}},
error: <nil>