Go:mapstructure包的使用

发布时间:2021-11-29 03:39:39

参考:goinggo/mapstructure
参考:package mapstructure




文章目录
1、导包2、使用目的3、Decode:map转换成结构体1、不支持内部结构体转换2、常规转换3、结论
4、DecodePath:复制内部某个结构体1、代码2、注意点3、time.Time的转换4、使用Decode方法替代
5、DecodeSlicePath:结构化切片1、切片处理2、结构体中包含切片的处理



1、导包

如果是Idea的话,在我们的Terminal上面输入命令,进行包的获取:


go get github.com/goinggo/mapstructure

正常是不会有问题,如果下载不下来报permission denie可以看一下我的这个文章:Git下载报错: Permission denied (publickey).问题解决



2、使用目的

官网的描述是这样的:

我的理解是说像map之类的结构,虽然用起来很方便,但是他麻烦的地方在于对于相应的结构信息不清晰,也就是说当你纯看代码的时候可能不知道具体里面有什么东西,而结构体就比较明确,他有多少属性, 什么类型等等,所以这里使用这个工具把map、json之类的进行转换其实也是为了能够得到结构体对象,数据结构更加清晰。



3、Decode:map转换成结构体
1、不支持内部结构体转换

看一下这一段代码,我这边添加了一个time的属性,本质上time是结构体,所以正常来说是不支持转换的。
Entity对象:


package entity

import "time"

type Entity struct {
Num int
S string
T time.Time
}


调用方法:


package main

import (
"fmt"
"github.com/goinggo/mapstructure"
"testProject/entity"
"time"
)

func MapStructureTestFunc() {
var te entity.Entity
m := make(map[string]interface{})
m["Num"] = 1
m["S"] = "test"
m["T"] = time.Now()

err := mapstructure.Decode(m, &te)
if err != nil {
panic(err.Error())
}

fmt.Print(te.Num, " ", te.S, " ", te.T)
}

直接运行我们这段代码看一下,断点在err处:
发现这边报了个错,不支持struct结构体的类型。但是可以支持map。


2、常规转换

所以我们把这边的T换成了map类型:
Entity对象:


package entity

type Entity struct {
Num int
S string
T map[string]string
}


运行方法:


package main

import (
"fmt"
"github.com/goinggo/mapstructure"
"testProject/entity"
)

func MapStructureTestFunc() {
var te entity.Entity
m := make(map[string]interface{})
m["Num"] = 1
m["S"] = "test"
m["T"] = map[string]string{"1": "1", "2": "2"}

err := mapstructure.Decode(m, &te)
if err != nil {
panic(err.Error())
}

fmt.Print(te.Num, " ", te.S, " ", te.T)
}


这一次没有报错了,查看一下我们的输出:


3、结论

1、该方法支持基本类型,不支持结构体 struct
2、该方法支持map结构中的值是map的嵌套结构


其实想来在java当中的BeanUtils的复制功能可能更强大一点,通过内省的方式实现同名类型的赋值。这里应该是没有考虑泛型的处理,之前看了源码太久忘了,java的对象操作,泛型相关的确实非常烦人。



4、DecodePath:复制内部某个结构体
1、代码

其实这个方法也是把整个的报文结构体复制下来,然后取其中的一些部分,怎么说呢,就是说他支持结构体中嵌套结构体的转换,而其实你取的只是其中一部分而已。我们看一下代码:


User实体


package entity

import "time"

type UserType struct {
UserTypeId int
UserTypeName string
}

type User struct {
UserType UserType `jpath:"userType"`
LoginName string `jpath:"loginName"`
T time.Time `jpath:"t"`
}


主方法:


package main

import (
"encoding/json"
"fmt"
"github.com/goinggo/mapstructure"
"testProject/entity"
)

var document = `{"loginName":"sptest1","userType":{"userTypeId":1,"userTypeName":"normal_user","t":"2026-01-02 15:04:05"}}`

func MapStructureTestFunc() {
var te entity.Entity
m := make(map[string]interface{})
m["Num"] = 1
m["S"] = "test"
m["T"] = map[string]string{"1": "1", "2": "2"}

err := mapstructure.Decode(m, &te)
if err != nil {
panic(err.Error())
}

fmt.Print(te.Num, " ", te.S, " ", te.T)
}

func MapStructureTestFunc1() {
var docMap map[string]interface{}
_ = json.Unmarshal([]byte(document), &docMap)

var user entity.User
err := mapstructure.DecodePath(docMap, &user)

if err != nil {
panic(err.Error())
}
fmt.Println(user.T.Format("2006-01-02 15:04:05"))
fmt.Println(user, " ", user.UserType.UserTypeId, " ", user.UserType.UserTypeName)
}


2、注意点

注意: 实体中的jpath的意思是结构体在数据中的别名,结构体字段必须是大写(非私有)才可见。
注意: 之前看网上有文章说字段和值得书写风格不一样转换不出来,我感觉这个很傻逼,如果真这么做的话那这个写api的人得花多少功夫去比较。


3、time.Time的转换

最后我尝试了一下这边的时间字段,无论是什么时间,好像都只会被转换成统一的数值,表示有点奇怪,这个还是没弄明白为啥


4、使用Decode方法替代

这边尝试了一下使用Decode方法也可以达到相应的目的,那这两个方法究竟有什么区别 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?



5、DecodeSlicePath:结构化切片
1、切片处理

如果是对切片的结构进行处理的话,直接使用DecodeSlicePath方法,我们来看下面的代码:


NameDoc实体


type NameDoc struct {
Name string `jpath:"name"`
}

主方法:


var document2 = `[{"name":"bill"},{"name":"lisa"}]`

func MapStructureTestFunc2() {

sliceScript := []byte(document2)
var sliceMap []map[string]interface{}
_ = json.Unmarshal(sliceScript, &sliceMap)

var myslice []NameDoc
err := mapstructure.DecodeSlicePath(sliceMap, &myslice)

if err != nil {
panic(err.Error())
}

fmt.Println(myslice[0], " ", myslice[1])
}

直接输出是正常的。其实还是不要忘了jpath这个东西.


2、结构体中包含切片的处理

如果说是一个结构体里面包含了切片的结构,比如说下面这个json串,使用DecodePath方法,按道理来说Decode方法应该也可以


Json串


{
"cobrandId": 10010352,
"channelId": -1,
"locale": "en_US",
"tncVersion": 2,
"people": [
{
"name": "jack",
"age": {
"birth":10,
"year":2000,
"animals": [
{
"barks":"yes",
"tail":"yes"
},
{
"barks":"no",
"tail":"yes"
}
]
}
},
{
"name": "jill",
"age": {
"birth":11,
"year":2001
}
}
]
}

看一下代码:


实体:


type Animal struct {
Barks string `jpath:"barks"`
}

type People struct {
Age int `jpath:"age.birth"` // jpath is relative to the array
Animals []Animal `jpath:"age.animals"`
}

type Items struct {
Categories []string `jpath:"categories"`
Peoples []People `jpath:"people"` // Specify the location of the array
}

主函数


var document1 = `{"cobrandId":10010352,"channelId":-1,"locale":"en_US","tncVersion":2,"people":[{"name":"jack","age":{"birth":10,"year":2000,"animals":[{"barks":"yes","tail":"yes"},{"barks":"no","tail":"yes"}]}},{"name":"jill","age":{"birth":11,"year":2001}}]}`

func MapStructureTestFunc3() {
docScript := []byte(document1)
var docMap map[string]interface{}
_ = json.Unmarshal(docScript, &docMap)

var items Items
err := mapstructure.DecodePath(docMap, &items)
if err != nil {
panic(err.Error())
}
fmt.Println(items.Peoples[0], items.Peoples[1])
}


官方doc还有更多详细的用法,可供参考。

相关文档

  • Spring中的声明事务管理,底层使用AOP思想
  • 企业文化演出小品
  • 保护校园环境的手抄报图片
  • 欧诗漫珍珠幻亮素颜雪肌乳怎么用
  • 华为荣耀6和畅玩5x哪个好
  • 和金牛男最配的星座是谁
  • 机器视觉开源处理库汇总-介绍n款计算机视觉库/人脸识别开源库/软件 -几种图像处理类库的比较-视觉相关网站
  • 《海底两万里》读后感1400字5篇
  • 昆虫日记350字(精选10篇)
  • 如何用手机打开dcm格式图片_日常手机办公篇:文档拍照快速转发分享
  • 祝福的话送给朋友短句大全 祝福朋友的优美句子2021
  • Redis、MySQL、hive、hbase的区别以及数据库及数据仓库的比较
  • 寻找计算机网络质量的峰值
  • python:网络数据收集
  • 我的朋友1000字范文5篇
  • 电脑wifi天线坏了怎么办
  • 学习linux决心书
  • 宝宝支气管肺炎怎么治
  • LTE学习笔记--MAC--BSR
  • 关于乡情600字作文(精选10篇)
  • 关于夏日黄昏的散文1000字
  • 风景优美的地方
  • 2020年上半年河南计算机软考考试推迟举行通知
  • /chroot环境搭建 - 定制的小型文件系统
  • 巧克力热量巧克力热量是多少
  • 励志加油的短语
  • 白萝卜干包大包子怎样处理白萝卜干
  • 珍惜时间的感悟作文
  • 百刷宝贝儿童电动牙刷好用吗百刷宝贝儿童电动牙刷怎么样
  • 企业策划书方案怎么写
  • 猜你喜欢

  • 【2018-2019】深情的毕业寄语集锦-word范文模板 (6页)
  • 城镇土地使用税采集表
  • 47489全上古三代秦汉三国六朝文六十二
  • 特种设备安全管理考核办法.docx
  • Java 线程通信
  • 高考语文二轮复*专题资料 第1部分 第7章 特色训练1 《〈论语〉选读》和其他典籍的组合训练
  • 各类节日庆典通用PPT模板 (9)
  • 2019年最新4月教师思想汇报范文:终生之爱,献给教育思想汇报文档【五篇】 (2)
  • 大学一句话优秀毕业感言
  • 《邪不压正》影评观后感
  • HashMap删除某个对象通过循环导致的java.util.ConcurrentModificationException
  • 中学生有哪些青春励志歌曲推荐
  • 2019-2020年人教统编中南大学有机化学—第九章羧酸及其衍生物幻灯片
  • 最新版湖南省益阳市高一下学期高一期末考试 数学 Word版含答案
  • 保险公司早会流程
  • 网络营销-微信行业解决方案(PPT39页)
  • 【教育资料】小学一年级语文第一册《复*二》第二课时教案
  • 破解Session cookie的方法
  • 小学美术教学中民间美术元素的渗入课题实施方案
  • 葫芦岛莲花山生活服务有限公司企业信用报告-天眼查
  • 青少版_新概念1A全单元课件_Unit_15(共22页).ppt
  • 高考数学二轮复*名师知识点总结不等式及线性规划
  • 天命3d怎么结婚的
  • 2018年秋人教版九年级化学(河北专版)习题课件:第八单元 课题2 第2课时 金属活动性顺序
  • 710000
  • 三年级作文:难忘的生日
  • 怎样做好高职院校合并后档案管理工作
  • 【目标管理】塔机质量目标管理控制程序
  • 最新感恩责任演讲稿
  • 2019-2020年高三下学期第一次测试理综化学试题 含答案
  • 精选-高考数学二轮复*指导冲刺:四个看与度-文档
  • 微信文章排版技巧总结
  • 维族消化性溃疡102例临床特点分析
  • xx幼儿园春季卫生保健工作计划范文
  • 2011届高三历史上册期中考试试题1
  • 广州市浩蕴依萘服装有限责任公司(企业信用报告)- 天眼查
  • 2019-2020年七年级上学期期末质量检测历史试题(II)
  • (整改方案)学校师德建设整改计划
  • 最新-七年级政治大家之家_图文.ppt-PPT文档资料
  • 学生课后作业问卷调查表
  • 有哪些是必备的单反配件
  • Docker ---- NFS共享存储
  • 电脑版