在Go语言中,encoding/json标准包处理json数据的序列化与反序列化问题。如果想了解序列化可以看这一篇序列化。与编码json的Marshal类似,解析json也提供了Unmarshal方法。对于解析json,也大致分两步,首先定义结构,然后调用Unmarshal方法序列化。

反序列化 Unmarshal()

反序列化源码放在:

Unmarshal

从上面的UnMarshal()函数我们可以看到,反序列化是读取字节数组,进而解析为对应的数据结构。

注意:

  1. 不是所有的数据都可以编码为 json 格式,只有验证通过的数据结构才能被编码:
  2. json 对象只支持字符串类型的 key;要编码一个 Go map 类型,map 必须是 map[string]T(T是 json 包中支持的任何类型)
  3. channel,复杂类型和函数类型不能被编码
  4. 不支持循环数据结构;它将引起序列化进入一个无限循环
  5. 指针可以被编码,实际上是对指针指向的值进行编码(或者指针是 nil)

而在Go中,json 与 Go 类型对应如下:

  1. bool 对应 json 的 booleans
  2. float64 对应 json 的 numbers
  3. string 对应 json 的 strings
  4. nil 对应 json 的 null


在解析 json 格式数据时,若以 interface{} 接收数据,需要按照以上规则进行解析。

反序列化成struct



输出结果:

定义了1个结构体Message ,结构体Message 的Address 字段tag标签为:json:“address”,表明这个字段在json中的名字对应为address。以此类推

jsonString 我们可以认作为一个json数据,通过json.Unmarshal,我们可以把json中的数据反序列化到了对应结构体。如果定义的字段address为小写,例如:


则会输出:

上面的password并不会被解析赋值json的password,大小写不敏感只是针对公有字段而言。再寻找tag或字段的时候匹配不成功,则会抛弃这个json字段的值:


这是我们在定义结构体时需要注意的,字段首字母大写。

反序列化成map

直接使用 Unmarshal 把这个数据反序列化,并保存map[string]interface{} 中,要访问这个数据,我们可以使用类型断言:



输出结果:

通过这种方式,即使是未知 json 数据结构,我们也可以反序列化,同时可以确保类型安全。

总结

golang和json的大部分数据结构匹配,对于复合结构,go语言可以借助结构体和空接口实现json的数组和对象结构。通过struct tag可以灵活的修改json编码的字段名和输出控制。


欢迎关注微信公众号【程序猿编码】,专注于Linux c/c++ 、Python、Go语言、数据结构与算法、网络编程相关知识,常用的程序员工具。还有每日00:10分之前更新 新闻简报,即刻知晓天下事!