大家使用这种弱类型解析的时候也需要注意 。
错误处理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,你学会了吗?】
推荐阅读
- 一文教你学会使用Nginx
- Go 语言为什么建议多使用切片,少使用数组?
- Java垃圾回收器的工作原理及监视不再使用对象的机制
- C++中new与malloc:内存分配机制深度解析
- 独立服务器是什么?基础知识与工作原理解析
- 酷路泽四驱怎么使用
- Go 语言使用 Echo 构建高性能 Web 应用
- Python Selenium实现自动化测试及Chrome驱动使用!
- C++中使用宏定义一个函数:灵活性与风险并存
- 作为 .NET 开发人员,我为什么开始使用 Python?
