序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。
我们的数据对象要在网络中传输或保存到文件,就需要对其编码和解码动作,目前存在很多编码格式:JSON,XML,Gob,Google Protocol Buffer等,Go 语言当然也支持所有这些编码格式。
在序列化期间,对象将其当前状态写入到临时或持久性存储区。通过从存储区中读取对象的状态,重新创建该对象,则为反序列化。
简单地说把某种数据结构转为指定数据格式为“序列化”或“编码”(传输之前);而把“指定数据格式”转为某种数据结构则为“反序列化”或“解码”(传输之后)。
在Go语言中,encoding/json标准包处理JSON数据的序列化与反序列化问题。
JSON数据序列化函数主要有:
//json.Marshal()
func Marshal(v interface{}) ([]byte, error) {
e := newEncodeState()
err := e.marshal(v, encOpts{escapeHTML: true})
if err != nil {
return nil, err
}
buf := append([]byte(nil), e.Bytes()...)
e.Reset()
encodeStatePool.Put(e)
return buf, nil
}
从上面的Marshal()函数我们可以看到,数据结构序列化后返回的是字节数组,而字节数组很容易通过网络传输或写入文件存储。而且在Go中,Marshal()默认是设置escapeHTML = true的,会自动把 '', 以及 '&' 等转化为"\u003c" , "\u003e"以及 "\u0026"。
JSON数据反序列化函数主要有:
// UnMarshal()
func Unmarshal(data []byte, v interface{}) error // 把 JSON 解码为数据结构
从上面的UnMarshal()函数我们可以看到,反序列化是读取字节数组,进而解析为对应的数据结构。
注意:不是所有的数据都可以编码为 JSON 格式,只有验证通过的数据结构才能被编码:
- JSON 对象只支持字符串类型的 key;要编码一个 Go map 类型,map 必须是 map[string]T(T是 JSON 包中支持的任何类型)
- channel,复杂类型和函数类型不能被编码
- 不支持循环数据结构;它将引起序列化进入一个无限循环
- 指针可以被编码,实际上是对指针指向的值进行编码(或者指针是 nil)
而在Go中,JSON 与 Go 类型对应如下:
- bool 对应 JSON 的 booleans
- float64 对应 JSON 的 numbers
- string 对应 JSON 的 strings
- nil 对应 JSON 的 null
在解析 JSON 格式数据时,若以 interface{}
接收数据,需要按照以上规则进行解析。
下一节:在Go语言中,利用encoding/json标准包将数据序列化为JSON数据格式这个过程简单直接,直接使用json.Marshal(v)来处理任意类型,序列化成功后得到一个字节数组。