在数据传递时,需要先编解码;常用的方式是JSON编解码(参见《golang之JSON处理》)。但有时却需要读取部分字段后,才能知道具体类型,此时就可借助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"`
}
mapstructure中可以使用Metadata收集一些解码时会产生的有用信息。
// mapstructure.go
type Metadata struct {
Keys []string // 解码成功的键
Unused []string // 源数据中存在,但目标结构中不存在的键
Unset []string // 未设定的(源数据中缺失的)键
}
为了获取这些信息,需要使用DecodeMetadata来解码:
var metadata mapstructure.Metadata
err := mapstructure.DecodeMetadata(m, &p, &metadata)
有时候,并不想对结构体字段类型和map[string]interface{}的对应键值做强类型一致的校验。这时可以使用WeakDecode/WeakDecodeMetadata方法,它们会尝试做类型转换:
除将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库深入详解的文章就介绍到这了,更多相关Go mapstructure内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
标签:
上一篇 : 环球速递!养虾遭遇“卡脖子”怎么破?这家企业真有“种”!|聊一聊高质量发展②
下一篇 : 最后一页
近日,巴西南部和中部多地遭遇极端天气侵袭,当地时间18日,巴西南里奥
06-20 14:31:31
当地时间6月19日,在法国举行的巴黎-布尔歇国际航空航天展览会上,法国
06-20 14:02:25
十二生肖都是哪些动物1、十二生肖,由12种源于自然界的动物即鼠、牛、
06-20 13:37:51
仔细研究男女面相后,可以发现除了骨相之外,嘴唇的差异也尤为明显。一
06-20 13:01:56
特别是每周五到周日的开赛日,还有好多车友从各地专门开车前往榕江现场
06-20 12:09:11
金投网提供2023版30克熊猫银币现在市场价是多少(2023年06月20日),(
06-20 11:55:34
企业运用互联网开展招聘,毕业生从招聘网站找工作,教育部门利用互联网
06-20 11:17:35
大家好,这里是【钛短评】栏目,我是短评君。【钛短评】是一档针对
06-20 11:09:00
团代表故事丨00后团代表刘羲檬:带着妈妈去支教
06-20 10:35:05
今天清晨,不少需搭乘沪宁城际铁路列车的乘客收到了列车停运的消息沪宁
06-20 10:09:09
人民币可以买港股啦!香港交易所6月19日正式推出“港币-人民币双柜台模
06-20 09:47:38
6月19日,市委书记朱是西到南阳中欧产业园现场办公时强调,坚定信心、
06-20 09:22:51
【大动作!华为成立新公司!白酒巨头火速出击入股一光伏企业!近10股将
06-20 09:03:22
篮球滑板等23个项目任选30天内40家定点泳池随便游全市中小学生夏令营21
06-20 08:15:22
号称美国最神秘私人精英俱乐部的波西米亚丛林俱乐部竟因克扣雇员工资被
06-20 07:34:10
一、承担违约责任的条件1、要有不履行合同的事实(这是认定违约责任的前
06-20 06:42:57
江西新闻客户端讯(江西日报全媒体记者周亚婧)近日,江西高速警察直属
06-20 05:38:15
1、1080P的资源MP4本来就不多79efb0c0daed2777c1f39d92b4be47aa3de3fc4c纯生
06-20 03:56:54
1、假如只是桌面木有图标,下边的开始条还有。2、就是某种原因造成你桌
06-20 01:12:47
1 首先,需要了解自己目前的健康状况和家庭病史。对于50岁的人来说,可
06-19 23:09:39
大小S一家的恩怨纠缠连续剧又更新了,这次主角是小S前男友黄子佼。最近
06-19 22:03:47
5月30日,MobvoiInc (以下简称,出门问问,国内运营主体:上海羽扇智
06-19 21:13:43
有投资者在投资者互动平台提问尊敬的董秘,全球800G光模块龙头“中际旭
06-19 20:44:21
上证报中国证券网讯(记者孔子元)退市未来公告,截至2023年6月19日,
06-19 19:55:16
中新社北京6月19日电综合消息:据巴勒斯坦官方通讯社“瓦法”报道,巴
06-19 19:36:31
开盘,汇市就异动了,A50就砸盘了,这个不在预期里面,所以没有三连阳
06-19 18:52:07
河北省文化和旅游厅关于对第三批智慧景区示范点创建单位入选名单的公示
06-19 18:22:43
真正爱好穿西装的男士,一定在选购西装的时候不会马虎。西服最讲究的就
06-19 17:45:33
(点击蓝色文字,免费咨询更年期健康问题)一、保持健康的生活方式
06-19 17:27:50
新京报讯(记者王子扬)6月19日,新京报记者了解到,三只松鼠日前在安徽
06-19 17:03:02
财联社6月17日讯(记者林坚)从受理到注册生效共仅用时95天,房地产“
06-19 16:26:12
奇瑞汽车于6月16日正式发布了2023款欧萌达车型,推出了新潮版、新潮PLU
06-19 16:09:22
格隆汇6月19日丨有投资者向木林森(002745 SZ)提问:一季度毛利率回暖原
06-19 15:35:04
6月13日,贵州歌手张恒远因黑色素瘤病逝,年仅36岁,他的告别仪式定在
06-19 15:17:53
信用卡欠款2个月未还怎么办?1、如果持卡人忘记还款,发现逾期后,一
06-19 14:49:49
我发现网上很多打着各种官方数据的名义,公布的却是山寨的战斗力数据,
06-19 14:00:22
6月19日盘中消息,13点2分和顺石油(603353)触及涨停板。目前价格18 4
06-19 13:26:51
凤凰网科技讯 6月19日消息,据天眼查App显示,近日,北京微播视界
06-19 12:31:17
公司精要:①2023年6月1日至6月17日,中药材综合200指数上涨9 12%,具
06-19 12:10:44
现货:6月16日,华北重碱2250元 吨(0),华东重碱2150元 吨(0),华中重
06-19 11:21:47
节气门多久清洗一次雅阁,节气门多久清洗这个很多人还不知道,现在让我
06-19 11:02:52
1、确保机械键盘有背景灯功能。2、打开方法:首先拿出一个有背景灯功能
06-19 10:50:34
经郑风子衿表达了怎样的内容,诗经郑风子衿这个问题很多朋友还不知道,
06-19 10:18:17
吉林:“数字政府”便民利企数字经济赋能振兴
06-19 09:42:24
1、删除烦恼,确认快乐,设定幸福,储存健康,勾销苦难,增添爱心,粘
06-19 09:34:58
库房拆迁补偿没有统一的标准,具体要根据库房的规模大小,综合评估仓库
06-19 09:31:34
1、定襄中学创办于1915年。1981年被确定为山西省首批重点中学。2009年1
06-19 09:00:03
近日,一则男扮女装进入郑州大学女澡堂偷拍的新闻引起了广泛的关注。这
06-19 09:08:33
最近几日蓉城体感比较舒爽但“清凉模式”可能要告急了今日成都太阳又“
06-19 09:02:53
哈喽,大家好,我是心尘,日常带你从不同的角度看斗罗大陆。斗罗1动漫
06-18 22:07:06
近日,巴西南部和中部多地遭遇极端天气侵袭,当地时间18日,巴西南里奥
2023-06-20
当地时间6月19日,在法国举行的巴黎-布尔歇国际航空航天展览会上,法国
2023-06-20
十二生肖都是哪些动物1、十二生肖,由12种源于自然界的动物即鼠、牛、
2023-06-20
仔细研究男女面相后,可以发现除了骨相之外,嘴唇的差异也尤为明显。一
2023-06-20
特别是每周五到周日的开赛日,还有好多车友从各地专门开车前往榕江现场
2023-06-20
7月7日,中国消费者协会、中国保健协会化妆品发展工作委员会联合发布暑期消费指示,保障儿童用妆安全。...
概念特点1、 定义:纤维是天然或人工合成的细丝状物质,纺织纤维则是指用来纺织布的纤维。2、 纺织纤...
中新网西宁11月21日电 题:青海水润高原:从“大动脉”到“毛细血管”的精准管理 作者 谈林明...
中新网西宁11月21日电 (记者 张添福)青海省卫生健康委员会21日消息,该省第3例本土确诊病例经过20...
新华社华盛顿11月20日电 通讯:“留在中国的决定让我拥有一段值得讲述的人生”——留华美国学生韩...
上市公司频获机构调研 接待机构来访量为20.89万家
Copyright © 2015-2023 港澳纤维网版权所有 备案号:京ICP备2023022245号-31 联系邮箱:435 226 40 @qq.com