使用 Mapstructure 解析 Json,你学会了吗?( 三 )

大家使用这种弱类型解析的时候也需要注意 。
错误处理mapstructure 错误提示非常的友好 , 下面我们来看看遇到错误时 , 它是怎么提示的 。
func decodeErrorHandle() { type Person struct {NamestringAgeintEmails []stringExtramap[string]string } input := map[string]interface{}{"name":123,"age":"bad value","emails": []int{1, 2, 3}, } var result Person err := mapstructure.Decode(input, &result) if err != nil {fmt.Println(err.Error()) }}输出:
5 error(s) decoding:* 'Age' expected type 'int', got unconvertible type 'string', value: 'bad value'* 'Emails[0]' expected type 'string', got unconvertible type 'int', value: '1'* 'Emails[1]' expected type 'string', got unconvertible type 'int', value: '2'* 'Emails[2]' expected type 'string', got unconvertible type 'int', value: '3'* 'Name' expected type 'string', got unconvertible type 'int', value: '123'这里的错误提示会告诉我们每个字段,字段里的值应该需要怎么表达 , 我们可以通过这些错误提示,比较快的去修复问题 。
总结从上面这些例子看看到 mapstructure 的强大之处,很好的帮我们解决了实实在在的问题,也在节省我们的开发成本 。
但是从源码来看,内部使用了大量的反射,这可能会对一些特殊场景带来性能隐患 。所以大家在使用的时候,一定要充分考虑产品逻辑以及场景 。
以下贴一小段删减过的源码:
// Decode decodes the given raw interface to the target pointer specified// by the configuration.func (d *Decoder) Decode(input interface{}) error { return d.decode("", input, reflect.ValueOf(d.config.Result).Elem())}// Decodes an unknown data type into a specific reflection value.func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) error { .... var err error outputKind := getKind(outVal) addMetaKey := true switch outputKind { case reflect.Bool:err = d.decodeBool(name, input, outVal) case reflect.Interface:err = d.decodeBasic(name, input, outVal) case reflect.String:err = d.decodeString(name, input, outVal) case reflect.Int:err = d.decodeInt(name, input, outVal) case reflect.Uint:err = d.decodeUint(name, input, outVal) case reflect.Float32:err = d.decodeFloat(name, input, outVal) case reflect.Struct:err = d.decodeStruct(name, input, outVal) case reflect.Map:err = d.decodeMap(name, input, outVal) case reflect.Ptr:addMetaKey, err = d.decodePtr(name, input, outVal) case reflect.Slice:err = d.decodeSlice(name, input, outVal) case reflect.Array:err = d.decodeArray(name, input, outVal) case reflect.Func:err = d.decodeFunc(name, input, outVal) default:// If we reached this point then we weren't able to decode itreturn fmt.Errorf("%s: unsupported type: %s", name, outputKind) } // If we reached here, then we successfully decoded SOMETHING, so // mark the key as used if we're tracking metainput. if addMetaKey && d.config.Metadata != nil && name != "" {d.config.Metadata.Keys = Append(d.config.Metadata.Keys, name) } return err}
【使用 Mapstructure 解析 Json,你学会了吗?】


推荐阅读