当前位置: 首页 > news >正文

c2c网站免费建设重庆网站备案快

c2c网站免费建设,重庆网站备案快,成都系统软件定制开发,wordpress上传源码介绍 先来介绍一下 mapstructure 这个库主要用来做什么的吧#xff0c;官网是这么介绍的#xff1a; mapstructure 是一个 Go 库#xff0c;用于将通用映射值解码为结构#xff0c;反之亦然#xff0c;同时提供有用的错误处理。 该库在解码数据流#xff08;JSON、Gob …介绍 先来介绍一下 mapstructure 这个库主要用来做什么的吧官网是这么介绍的 mapstructure 是一个 Go 库用于将通用映射值解码为结构反之亦然同时提供有用的错误处理。 该库在解码数据流JSON、Gob 等中的值时最为有用因为在读取部分数据之前您并不十分清楚底层数据的结构。因此您可以读取 map[string]interface{} 并使用此库将其解码为适当的本地 Go 底层结构。 简单来说它擅长解析一些我们并不十分清楚底层数据结构的数据流到我们定义的结构体中。 下面我们通过几个例子来简单介绍一下 mapstructure 怎么使用。 例子 普通形式 func normalDecode() {type Person struct {Name stringAge intEmails []stringExtra map[string]string}// 此输入可以来自任何地方但通常来自诸如解码 JSON 之类的东西我们最初不太确定结构。input : map[string]interface{}{name: Tim,age: 31,emails: []string{onegmail.com, twogmail.com, threegmail.com},extra: map[string]string{twitter: Tim,},}var result Personerr : mapstructure.Decode(input, result)if err ! nil {panic(err)}fmt.Printf(%#v\n, result) } 输出 main.Person{Name:Tim, Age:31, Emails:[]string{onegmail.com, twogmail.com, threegmail.com}, Extra:map[string]string{twitter:Tim}} 这个方式应该是我们最经常使用的非常简单的将 map[string]interface{} 映射到我们的结构体中。 在这里我们并没有指定每个 field 的 tag让 mapstructure 自动去映射。 如果我们的 input 是一个 json 字符串那么我们需要将 json 字符串解析为 map[string]interface{} 之后再将其映射到我们的结构体中。 func jsonDecode() {var jsonStr {name: Tim,age: 31,gender: male }type Person struct {Name stringAge intGender string}m : make(map[string]interface{})err : json.Unmarshal([]byte(jsonStr), m)if err ! nil {panic(err)}var result Personerr mapstructure.Decode(m, result)if err ! nil {panic(err.Error())}fmt.Printf(%#v\n, result) } 输出 main.Person{Name:Tim, Age:31, Gender:male} 嵌入式结构 mapstructure 允许我们压缩多个嵌入式结构并通过 squash 标签进行处理。 func embeddedStructDecode() {// 使用 squash 标签允许压缩多个嵌入式结构。通过创建多种类型的复合结构并对其进行解码来演示此功能。type Family struct {LastName string}type Location struct {City string}type Person struct {Family mapstructure:,squashLocation mapstructure:,squashFirstName string}input : map[string]interface{}{FirstName: Tim,LastName: Liu,City: China, Guangdong,}var result Personerr : mapstructure.Decode(input, result)if err ! nil {panic(err)}fmt.Printf(%s %s, %s\n, result.FirstName, result.LastName, result.City) } 输出 Tim Liu, China, Guangdong 在这个例子中 Person 里面有着 Location 和 Family 的嵌入式结构体通过 squash 标签进行压缩从而达到平铺的作用。 元数据 func metadataDecode() {type Person struct {Name stringAge intGender string}// 此输入可以来自任何地方但通常来自诸如解码 JSON 之类的东西我们最初不太确定结构。input : map[string]interface{}{name: Tim,age: 31,email: onegmail.com,}// 对于元数据我们制作了一个更高级的 DecoderConfig以便我们可以更细致地配置所使用的解码器。在这种情况下我们只是告诉解码器我们想要跟踪元数据。var md mapstructure.Metadatavar result Personconfig : mapstructure.DecoderConfig{Metadata: md,Result: result,}decoder, err : mapstructure.NewDecoder(config)if err ! nil {panic(err)}if err decoder.Decode(input); err ! nil {panic(err)}fmt.Printf(value: %#v, keys: %#v, Unused keys: %#v, Unset keys: %#v\n, result, md.Keys, md.Unused, md.Unset) } 输出 value: main.Person{Name:Tim, Age:31, Gender:}, keys: []string{Name, Age}, Unused keys: []string{email}, Unset keys: []string{Gender} 从这个例子我们可以看出使用 Metadata 可以记录我们结构体以及 map[string]interface{} 的差异相同的部分会正确映射到对应的字段中而差异则使用了 Unused 和 Unset 来表达。 Unusedmap 中有着结构体所没有的字段。 Unset结构体中有着 map 中所没有的字段。 避免空值的映射 这里的使用其实和内置的 json 库使用方式是一样的都是借助 omitempty 标签来解决。 func omitemptyDecode() {// 添加 omitempty 注释以避免空值的映射键type Family struct {LastName string}type Location struct {City string}type Person struct {*Family mapstructure:,omitempty*Location mapstructure:,omitemptyAge intFirstName string}result : map[string]interface{}{}input : Person{FirstName: Somebody}err : mapstructure.Decode(input, result)if err ! nil {panic(err)}fmt.Printf(%v\n, result) } 输出 map[Age:0 FirstName:Somebody] 这里我们可以看到 *Family 和 *Location 都被设置了 omitempty所以在解析过程中会忽略掉空值。而 Age 没有设置并且 input 中没有对应的 value所以在解析中使用对应类型的零值来表达而 int 类型的零值就是 0。 剩余字段 func remainDataDecode() {type Person struct {Name stringAge intOther map[string]interface{} mapstructure:,remain}input : map[string]interface{}{name: Tim,age: 31,email: onegmail.com,gender: male,}var result Personerr : mapstructure.Decode(input, result)if err ! nil {panic(err)}fmt.Printf(%#v\n, result) } 输出 main.Person{Name:Tim, Age:31, Other:map[string]interface {}{email:onegmail.com, gender:male}} 从代码可以看到 Other 字段被设置了 remain这意味着 input 中没有正确映射的字段都会被放到 Other 中从输出可以看到email 和 gender 已经被正确的放到 Other 中了。 自定义标签 func tagDecode() {// 请注意结构类型中定义的 mapstructure 标签可以指示将值映射到哪些字段。type Person struct {Name string mapstructure:person_nameAge int mapstructure:person_age}input : map[string]interface{}{person_name: Tim,person_age: 31,}var result Personerr : mapstructure.Decode(input, result)if err ! nil {panic(err)}fmt.Printf(%#v\n, result) } 输出 main.Person{Name:Tim, Age:31} 在 Person 结构中我们将 person_name 和 person_age 分别映射到 Name 和 Age 中从而达到在不破坏结构的基础上去正确的解析。 弱类型解析 正如前面所说mapstructure 提供了类似 PHP 解析弱类型结构的方法。 func weaklyTypedInputDecode() {type Person struct {Name stringAge intEmails []string}// 此输入可以来自任何地方但通常来自诸如解码 JSON 之类的东西由 PHP 等弱类型语言生成。input : map[string]interface{}{name: 123, // number stringage: 31, // string numberemails: map[string]interface{}{}, // empty map empty array}var result Personconfig : mapstructure.DecoderConfig{WeaklyTypedInput: true,Result: result,}decoder, err : mapstructure.NewDecoder(config)if err ! nil {panic(err)}err decoder.Decode(input)if err ! nil {panic(err)}fmt.Printf(%#v\n, result) } 输出 main.Person{Name:123, Age:31, Emails:[]string{}} 从代码可以看到input 中的 name、age 和 Person 结构体中的 Name、Age 类型不一致而 email 更是离谱一个字符串数组一个是 map。 但是我们通过自定义 DecoderConfig将 WeaklyTypedInput 设置成 true 之后mapstructure 很容易帮助我们解决这类弱类型的解析问题。 但是也不是所有问题都能解决通过源码我们可以知道有如下限制 // - bools to string (true 1, false 0) // - numbers to string (base 10) // - bools to int/uint (true 1, false 0) // - strings to int/uint (base implied by prefix) // - int to bool (true if value ! 0) // - string to bool (accepts: 1, t, T, TRUE, true, True, 0, f, F, // FALSE, false, False. Anything else is an error) // - empty array empty map and vice versa // - negative numbers to overflowed uint values (base 10) // - slice of maps to a merged map // - single values are converted to slices if required. Each // element is weakly decoded. For example: 4 can become []int{4} // if the target type is an int slice. 大家使用这种弱类型解析的时候也需要注意。 错误处理 mapstructure 错误提示非常的友好下面我们来看看遇到错误时它是怎么提示的。 func decodeErrorHandle() {type Person struct {Name stringAge intEmails []stringExtra map[string]string}input : map[string]interface{}{name: 123,age: bad value,emails: []int{1, 2, 3},}var result Personerr : 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 erroroutputKind : getKind(outVal)addMetaKey : trueswitch 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 werent 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 were tracking metainput.if addMetaKey d.config.Metadata ! nil name ! {d.config.Metadata.Keys append(d.config.Metadata.Keys, name)}return err }
http://www.zqtcl.cn/news/549323/

相关文章:

  • 学习前端开发的网站动漫设计属于什么大类
  • 十堰秦楚网 十堰新闻门户网站报修网站模板
  • 家居小程序源码下载自动seo系统
  • 动态效果的网站建设技术老闵行是指哪里
  • 电商网站开发面临的技术问题做闪图的网站
  • 怎么查看网站开发语言的类型东莞哪些地方是风险区
  • 不用购买域名做网站广州网站建设培训学校
  • 城市轨道建设规范下载网站古网站典模板
  • 关于实验室建设的英文网站深圳企业网站制作公司怎样
  • wordpress全站背景音乐中山网站搜索排名
  • 搭建网站的过程透明主题wordpress
  • 丰台网站建设公司电话深圳微信商城网站设计公司
  • 做淘宝要用的网站吗上海微信网站
  • 佛山高端网站制作公司wordpress 发送邮件插件
  • 类似站酷的设计类网站网站建设需要待摊吗
  • 用php做视频网站在学做网站还不知道买什么好
  • wordpress培训类网站网站建设 好
  • 网站开发需要2个月吗网站建设案例精粹
  • 网站建设项目职责营销型网站建设五大内容
  • 建设工程监理招标网站W做网站
  • 网站建设与维护教学课件网站上线前做环境部署
  • 信誉好的网站建设做网站成为首富的外国人
  • 常州网站制作市场湖北省荆门市城乡建设网站
  • 泉州网站制作运营商专业北京软件公司招聘信息查询
  • 车床加工东莞网站建设网站建设教学改进
  • 深圳专业做网站建设西安网站建设有限公司
  • wordpress 一键建站wordpress子主题style
  • 昆明设计网站怎么做网络广告
  • 2018什么做网站深圳企业网站设
  • 北京旅游外贸网站建设博客集成wordpress