博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
golang自定义json encode
阅读量:7052 次
发布时间:2019-06-28

本文共 1861 字,大约阅读时间需要 6 分钟。

hot3.png

golang json自定义encode

简介

golang原生提供了很方便的json处理,例如struct转为json时,直接在成员变量上使用 `json:"name"` 来设置json的字段。一般情况下,对于基础类型 json.Marshal(object) 都可以满足需求,但对于特殊情况就需要通过自定义的json encode解决了。

特殊情况

golang官方推荐提供的set方案是通过map来实现的

custormSet := make(map [CustormStruct] bool)custormObj := custorm.NextObj()if _,ok := custormSet[custormObj];!ok{    custormSet[custormObj] = true}

通过这样方法来实现集合的功能。

问题是如果一个struct中需要一个set类型的成员变量,并需要转为json。如果直接使用 json.Marshal(object) ,对应类型就会变成一个map,而非我们需要的元素不重复的list。

解决方法

案例简介

统计所有访问过本地某个端口的ip,具体数据采集的方法有好几种,不是本文的重点就不介绍了。

实现

type ListenPort struct{	Port int	ipSet map[string] bool	ipList []*string}func NewPort(port int) ListenPort{	ipSet := make(map[string] bool)	ipList := []*string{}	return ListenPort{		port,		ipSet,		ipList,	}}func (p *ListenPort)Add(ip string)  {	if _,ok:= p.ipSet[ip];!ok{		p.ipSet[ip] = true		p.ipList = append(p.ipList,&ip)	}}//敲黑板!!!这是重点func (p ListenPort)MarshalJSON() ([]byte, error){	return json.Marshal(&struct {		Port int       `json:"port"`		Ips  []*string `json:"ip"`	}{		Port: p.Port,		Ips:  p.ipList,	})}

测试代码

ipPort := NewPort(2333)ipPort.Add("127.0.0.1")ipPort.Add("116.211.174.177")ipPort.Add("106.39.167.11")ipPort.Add("220.181.57.2168")ipPort.Add("127.0.0.1")jsonbyte,err := json.Marshal(ipPort)if err != nil {	fmt.Println(err)}fmt.Println(string(jsonbyte))

说明

func (obj ObjectType)MarshalJSON() ([]byte, error) 方法应该是实现了json的某个接口。通过重新构造一个struct来解决这个问题。

代码是我原创的,方法是我google的

额外说明

  • 为什么不用反射?

通过实验可以发现对于reflect对于map,通过以下代码得到的就是一个key list。以下代码打印的结果与打印 p.ipList 一样

func (p *ListenPort)PrintlnIpList(){    fmt.Println(reflect.ValueOf(p.ipSet).MapKeys())}

经过尝试发现,直接使用json转换reflect.Value类型的变量得到的是一个 {}

  • 为什么选择增加一个slice?

实际上新增了slice储存的是string的地址,并不会增加多少内存。对于reflect.Value类型的确有方法将其再次转换成string类型。只不过每次获取json转换都需要遍历一次slice,这需要自己权衡。

  • emmmm

ipSet 和ipList为私有成员变量,纯属看业务场景需要

小结

~blablabla~

转载于:https://my.oschina.net/u/3703365/blog/1813135

你可能感兴趣的文章
python学习笔记一
查看>>
Gym 100283F Bakkar In The Army
查看>>
POJ 2947 2947 Widget Factory 高斯消元
查看>>
ExtJS-3.4.0系列:Ext.TabPanel
查看>>
在Eclipse中配置Heritrix-1.14.4版本
查看>>
设计模式笔记:开闭原则(OCP,The Open-Closed Principle)
查看>>
Sql Server系列:键和约束
查看>>
服务器负载感知的URL HASH
查看>>
java xml操作
查看>>
关于Android SDK无法正常下载
查看>>
LVS-DR演示
查看>>
我的友情链接
查看>>
硬件要求
查看>>
基本数据类型
查看>>
我的友情链接
查看>>
C#常见问题总结(二)
查看>>
cmder使用技巧
查看>>
关于dns使用协议的探究
查看>>
我的友情链接
查看>>
我的友情链接
查看>>