Golang实现Json序列化
学习自:https://golang.org/pkg/encoding/json/#Marshal
先来看看api的使用:
1 | func Marshal(v interface{}) ([]byte, error) |
基本作用就是返回v的json编码
作用过程
Marshal递归地遍历v,如果遇到实现了Marshaler接口的值并且不是nil指针,Marshal会调用MarshalJSON方法来生成JSON。如果不存在MarshalJSON方法,但该值实现了encoding.TextMarshaler,则Marshal会调用MarshalText方法将结果编码为JSON字符。
编码结果
Marshal使用以下类型相关的默认编码:
- bool值编码为JSON的布尔值;
- 浮点数、整数和number值编码为JSON数字
- 字符串值编码为有效的UTF-8的JSON字符串,并且会用Unicode替换无效字节
为了防止某些浏览器会将JSON输出解析为HTML,尖括号<和>被转义为03c和03e。基于相同的原因,符号&会被转义为026
可以使用调用了SetEscapeHTML(false)的编码器禁止此转义
- 数组和切片值编码为JSON数组,但了[]字节会被编码为base64编码的字符串,而nil切片编码为空JSON值
- 结构体则是编码为JSON对象,每个structure字段都会成为JSON对象的成员,并且会使用该字段名称作为对象值
关于structure编码为JSON
在golang的结构体中,每个成员变量都可以附带一个Tag说明,因此每个struct字段的编码可以通过存储在以Json为key的tag进行定制化。比如:
1 | type User struct { |
这些格式化字符串给出了字符的名称,还可以通过逗号在后面加上一系列的选项。tag中如果带有”omitempty”选项,那么如果该字段值为空,就不会输出到JSON串中。
还有一种特别的情况,如果字段标记为“ - ”,则始终省略该字段。请注意,比较特别的是仍然可以使用标记“ - ,”生成名称为“ - ”的字段。比如:
1 | // Field is ignored by this package. |
“string”选项表示字段在JSON编码的字符串中存储为JSON。它仅适用于字符串,浮点,整数或布尔类型的字段。在与JavaScript程序通信时,有时会使用这种额外的编码级别。
其它
map
map被编码为JSON对象,而且map的key类型必须是字符串、整数或者实现了encoding.TextMarshaler。其中:
- 字符串类型会被直接实现
- encoding.TextMarshaler的会被marshaled
- 整数则会转为字符串
接口
接口会被编码为接口中包含的值,nil接口值则被编码为null JSON值
另外:
Channel, complex, and function values cannot be encoded in JSON. Attempting to encode such a value causes Marshal to return an UnsupportedTypeError.
例子
1 | package main |