iis服务器助手广告
返回顶部
首页 > 资讯 > 后端开发 > GO >Golang结构体映射mapstructure库怎么使用
  • 871
分享到

Golang结构体映射mapstructure库怎么使用

2023-07-04 21:07:16 871人浏览 八月长安
摘要

这篇文章主要介绍“golang结构体映射mapstructure库怎么使用”,在日常操作中,相信很多人在Golang结构体映射mapstructure库怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”G

这篇文章主要介绍“golang结构体映射mapstructure库怎么使用”,在日常操作中,相信很多人在Golang结构体映射mapstructure库怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Golang结构体映射mapstructure库怎么使用”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

    在数据传递时,需要先编解码;常用的方式是JSON编解码。但有时却需要读取部分字段后,才能知道具体类型,此时就可借助mapstructure库了。

    mapstructure库

    mapstructure可方便地实现map[string]interface{}struct间的转换;使用前,需要先导入库:

    go get GitHub.com/mitchellh/mapstructure

    字段标签

    默认情况下,mapstructure使用字段的名称做匹配映射(即在map中以字段名为键值查找字段值);注意匹配时是忽略大小写的。也可通过标签来设定字段映射名称:

    type Person struct {  Name string `mapstructure:"userName"`}

    内嵌结构

    go中结构体是可以任意嵌套的;嵌套后即认为拥有对应的字段。但是,默认情况下mapstructure只处理当前结构定义的字段,若要自动处理内嵌字段需要添加标签squash

    type Student struct {  Person `mapstructure:",squash"`  Age int }

    未映射字段

    若源数据中有未映射的值(即结构体中无对应的字段),mapstructure默认会忽略它。可以在结构体中定义一个特殊字段(类型为map[string]interface{},且标签要设置为mapstructure:",remain"),来存放所有未能映射的字段中。

    type Student struct {  Name  string  Age   int  Other map[string]interface{} `mapstructure:",remain"`}

    Metadata

    mapstructure中可以使用Metadata收集一些解码时会产生的有用信息。

    // mapstructure.gotype Metadata struct {  Keys   []string  // 解码成功的键  Unused []string  // 源数据中存在,但目标结构中不存在的键  Unset  []string  // 未设定的(源数据中缺失的)键}

    为了获取这些信息,需要使用DecodeMetadata来解码:

      var metadata mapstructure.Metadata
      err := mapstructure.DecodeMetadata(m, &p, &metadata)

    弱类型输入

    有时候,并不想对结构体字段类型和map[string]interface{}的对应键值做强类型一致的校验。这时可以使用WeakDecode/WeakDecodeMetadata方法,它们会尝试做类型转换:

    • 布尔转字符串:true = “1”, false = “0”;

    • 布尔转数字:true = 1, false = 0;

    • 数字转布尔:true if value != 0;

    • 字符串转布尔:可接受,

    • 真:1, t, T, TRUE, true, True

    • 假:0, f, F, FALSE, false, False

    • 数字转字符串:自动base10转换;

    • 负数转为无符号数(上溢);

    • 字符串转数字:根据前缀(如0x等)转换;

    • 数组与空map间互转;

    • 单个值转为切片;

    逆向转换

    除将map转换为结构体外,mapstructure也可以将结构体反向解码为map[string]interface{}。在反向解码时,我们可以为某些字段设置mapstructure:“,omitempty”,当这些字段为默认值时,就不会出现在map中:

      p := &Student{    Name: "Mike",    Age:  12,  }  var m map[string]interface{}  mapstructure.Decode(p, &m)

    解码器

    mapstructure提供了解码器(Decoder),可灵活方便地控制解码:

    type DecoderConfig struct {    // 若设定,则在任何解码或类型转换(设定了WeaklyTypedInput)前调用;对于设定了squash的内嵌字段,整体调用一次;若返回错误,则整个解码失败    DecodeHook DecodeHookFunc    // 若设定,则源数据中存在未使用字段时,报错    ErrorUnused bool    // 若设定,则有字段未设定时,报错    ErrorUnset bool    // 若设定,则在设定字段前先清空(对于map等类型会先清理掉旧数据)    ZeroFields bool    // 若设定,支持若类型间的转换    WeaklyTypedInput bool    // Squash will squash embedded structs.     Squash bool    // Metadata is the struct that will contain extra metadata about    // the decoding. If this is nil, then no metadata will be tracked.    Metadata *Metadata    // Result is a pointer to the struct that will contain the decoded    // value.    Result interface{}    // The tag name that mapstructure reads for field names. This    // defaults to "mapstructure"    TagName string    // IgnoreUntaggedFields ignores all struct fields without explicit    // TagName, comparable to `mapstructure:"-"` as default behaviour.    IgnoreUntaggedFields bool    // MatchName is the function used to match the map key to the struct    // field name or tag. Defaults to `strings.EqualFold`. This can be used    // to implement case-sensitive tag values, support snake casing, etc.    MatchName func(mapKey, fieldName string) bool}

    一个支持弱类型转换的示例:要获取的结果放到config的result中

        Name string    Age  int}func decoderConfig() {    m := map[string]interface{}{        "name": 123,        "age":  "12",        "job":  "programmer",    }    var p Person    var metadata mapstructure.Metadata    decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{        WeaklyTypedInput: true,        Result:           &p,        Metadata:         &metadata,    })    if err != nil {        log.Fatal(err)    }    err = decoder.Decode(m)    if err == nil {        log.Printf("Result: %#v", p)        log.Printf("keys:%#v, unused:%#v\n", metadata.Keys, metadata.Unused)    } else {        log.Println("decode fail:", err)    }}

    示例

    通过一个messageData结构,action会指示最终的data类型。接收到数据后,先解析出atcion,再根据action转换为真实的类型。

    因time.Time是一个结构体(json序列化时会转换为时间字符串),mapstructure无法正确处理,所以推荐使用时间戳。

    为了能正确解析内嵌的DataBasic,需要标记为squash。

    import "github.com/mitchellh/mapstructure"type DataBasic struct {    DataId     string `json:"dataId"`    UpdateTime int64  `json:"updateTime"`}type AddedData struct {    DataBasic `mapstructure:",squash"`    Tag string `json:"tag"`    AddParams map[string]any `json:"addParams"`}type messageData struct {    Action    int    `json:"action"`    SeqId     uint64 `json:"seqId"`    Data      any    `json:"data"`}func decodeData() {    add := &AddedData{        DataBasic: DataBasic{            DataId:     "a2",            UpdateTime: time.Now().UnixMilli(),        },        Tag: "tag",        AddParams:  map[string]any{"dataId": "c2", "otherId": "t2"},    }    data := &messageData{        Action: 1,        Data:   add,    }    js, err := json.Marshal(data)    if err != nil {        log.Printf("marshal fail: %v", err)        return    }    got := &messageData{}    err = json.Unmarshal(js, got)    if err != nil {        log.Printf("unmarshal fail: %v", err)        return    }    param := new(AddedData)    err = mapstructure.Decode(got.Data, param)    if err != nil {        log.Printf("unmarshal fail: %v", err)        return    }    log.Printf("param: %+v", param)}

    到此,关于“Golang结构体映射mapstructure库怎么使用”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

    您可能感兴趣的文档:

    --结束END--

    本文标题: Golang结构体映射mapstructure库怎么使用

    本文链接: https://www.lsjlt.com/news/347777.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • Golang结构体映射mapstructure库怎么使用
      这篇文章主要介绍“Golang结构体映射mapstructure库怎么使用”,在日常操作中,相信很多人在Golang结构体映射mapstructure库怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”G...
      99+
      2023-07-04
    • Golang中结构体映射mapstructure库深入详解
      目录mapstructure库字段标签内嵌结构未映射字段Metadata弱类型输入逆向转换解码器示例在数据传递时,需要先编解码;常用的方式是JSON编解码(参见《golang之JSO...
      99+
      2023-01-02
      Go结构体映射mapstructure Go mapstructure Go结构体映射
    • 在 Golang 的结构体中分配切片映射
      各位小伙伴们,大家好呀!看看今天我又给各位带来了什么文章?本文标题是《在 Golang 的结构体中分配切片映射》,很明显是关于Golang的文章哈哈哈,其中内容主要会涉及到等等,如果能帮到你,觉得很...
      99+
      2024-04-04
    • golang怎么用反射reflect操作结构体
      这篇文章给大家分享的是有关golang怎么用反射reflect操作结构体的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。golang的优点golang是一种编译语言,可以将代码编译为机器代码,编译后的二进制文件可以...
      99+
      2023-06-14
    • golang 如何用反射reflect操作结构体
      背景 需要遍历结构体的所有field 对于exported的field, 动态set这个field的value 对于unexported的field, 通过强行取址的方法来获取该值(...
      99+
      2024-04-02
    • 使用泛型将结构转换为映射
      最近发现不少小伙伴都对Golang很感兴趣,所以今天继续给大家介绍Golang相关的知识,本文《使用泛型将结构转换为映射》主要内容涉及到等等知识点,希望能帮到你!当然如果阅读本文时存在不同想法,可以...
      99+
      2024-04-04
    • 映射接口{}和类型结构体{}有什么区别?
      问题内容 我刚刚读到,map[Type]interface{} 指定了 Type 类型的键的映射,其值为any,即interface{}。 这不是与定义结构几乎相同吗,即 type N...
      99+
      2024-02-06
      键值对
    • 使用Golang反射实现结构体字段遍历与修改
      go 反射可以用于遍历和修改结构体字段。字段遍历:使用 reflect.typeof 和 reflect.field 遍历结构体字段。字段修改:通过 elem 和 set 来访问和修改结...
      99+
      2024-04-03
      java 关键词: php golang
    • 怎么使用golang range遍历结构体数组
      你可以使用range关键字来遍历结构体数组。下面是一个简单的例子: package main import "fmt" type...
      99+
      2023-10-22
      golang
    • C#结构体怎么使用
      本篇内容介绍了“C#结构体怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!实例using System;using ...
      99+
      2023-06-17
    • ASP.NET Core扩展库之实体映射使用详解
      目录一、启用二、配置自定义转换逻辑三、使用四、通过特性指定属性映射关系五、拷贝六、示例在分层设计模式中,各层之间的数据通常通过数据传输对象(DTO)来进行数据的传递,而大多数情况下,...
      99+
      2024-04-02
    • Golang怎么使用gob实现结构体的序列化
      本文小编为大家详细介绍“Golang怎么使用gob实现结构体的序列化”,内容详细,步骤清晰,细节处理妥当,希望这篇“Golang怎么使用gob实现结构体的序列化”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。Gol...
      99+
      2023-07-05
    • C++ Struct结构体怎么使用
      今天小编给大家分享一下C++ Struct结构体怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。一.C语言 ...
      99+
      2023-07-05
    • Golang怎么实现Json转结构体
      这篇文章主要讲解了“Golang怎么实现Json转结构体”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Golang怎么实现Json转结构体”吧!请求Zabbix API,通过itemid获取...
      99+
      2023-07-05
    • MyBatis中怎么使用ResultMap进行结果集映射
      在 MyBatis 中,可以使用 ResultMap 进行结果集映射。ResultMap 是一个 XML 元素,用来描述如何将查询结...
      99+
      2024-04-08
      MyBatis
    • golang中使用匿名结构体的方法
      目录转化为map定义具名结构体定义匿名结构体在一些项目中, 我们会使用json 来将字符串转为结构体,但是很多时候,这种结构体只会用一次,基本上只会用于反序列化, 对于这种只用到一次...
      99+
      2024-04-02
    • Go语言中怎么实现结构体反射
      本篇文章给大家分享的是有关Go语言中怎么实现结构体反射,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。结构体type Student struct ...
      99+
      2023-06-15
    • Linux的file结构体和inode结构体怎么用
      本篇内容介绍了“Linux的file结构体和inode结构体怎么用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1. file 结构体fil...
      99+
      2023-06-27
    • golang结构体序列化怎么实现
      在Go中,可以使用encoding/json包来实现结构体的序列化和反序列化。 首先,需要导入encoding/json包: imp...
      99+
      2023-10-22
      golang
    • Golang 利用反射对结构体优雅排序的操作方法
      最近开始实习,工作技术栈主要Python和Golang,目前的任务把Python模块重构为GO模块,然后出现了一个问题,就是要将一个结构体按结构体中各个字段进行排序,然后写入Redi...
      99+
      2024-04-02
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作