Gob 是 Go 自己的以二进制形式序列化和反序列化程序数据的格式;可以在 encoding 包中找到。这种格式的数据简称为 Gob (即 Go binary 的缩写)。类似于 Python 的 “pickle” 和 Java 的 “Serialization”。
Gob 通常用于远程方法调用(RPCs,参见 15.9 的 rpc 包)参数和结果的传输,以及应用程序和机器之间的数据传输。 它和 JSON 或 XML 有什么不同呢?Gob 特定地用于纯 Go 的环境中,例如,两个用 Go 写的服务之间的通信。这样的话服务可以被实现得更加高效和优化。 Gob 不是可外部定义,语言无关的编码方式。因此它的首选格式是二进制,而不是像 JSON 和 XML 那样的文本格式。 Gob 并不是一种不同于 Go 的语言,而是在编码和解码过程中用到了 Go 的反射。
Gob 文件或流是完全自描述的:里面包含的所有类型都有一个对应的描述,并且总是可以用 Go 解码,而不需要了解文件的内容。
只有可导出的字段会被编码,零值会被忽略。在解码结构体的时候,只有同时匹配名称和可兼容类型的字段才会被解码。当源数据类型增加新字段后,Gob 解码客户端仍然可以以这种方式正常工作:解码客户端会继续识别以前存在的字段。并且还提供了很大的灵活性,比如在发送者看来,整数被编码成没有固定长度的可变长度,而忽略具体的 Go 类型。
例1:数据结构与bytes.Buffer之间的转换(编码成字节切片)
package main
import (
"bytes"
"fmt"
"encoding/gob"
"io"
)
//准备编码的数据
type P struct {
X, Y, Z int
Name string
}
//接收解码结果的结构
type Q struct {
X, Y *int32
Name string
}
func main() {
//初始化一个数据
data := P{3, 4, 5, "CloudGeek"}
//编码后得到buf字节切片
buf := encode(data)
//用于接收解码数据
var q *Q
//解码操作
q = decode(buf)
//"CloudGeek": {3,4}
fmt.Printf("%q: {%d,%d}\n", q.Name, *q.X, *q.Y)
}
func encode(data interface{}) *bytes.Buffer {
//Buffer类型实现了io.Writer接口
var buf bytes.Buffer
//得到编码器
enc := gob.NewEncoder(&buf)
//调用编码器的Encode方法来编码数据data
enc.Encode(data)
//编码后的结果放在buf中
return &buf
}
func decode(data interface{}) *Q {
d := data.(io.Reader)
//获取一个解码器,参数需要实现io.Reader接口
dec := gob.NewDecoder(d)
var q Q
//调用解码器的Decode方法将数据解码,用Q类型的q来接收
dec.Decode(&q)
return &q
}
例2:数据结构到文件的序列化和反序列化
package main
import (
"encoding/gob"
"os"
"fmt"
)
//试验用的数据类型
type Address struct {
City string
Country string
}
//序列化后数据存放的路径
var filePath string
func main() {
filePath = "./address.gob"
encode()
pa := decode()
fmt.Println(*pa) //{Chengdu China}
}
//将数据序列号后写到文件中
func encode() {
pa := &Address{"Chengdu", "China"}
//打开文件,不存在的时候新建
file, _ := os.OpenFile(filePath, os.O_CREATE|os.O_WRONLY, 0666)
defer file.Close()
//encode后写到这个文件中
enc := gob.NewEncoder(file)
enc.Encode(pa)
}
//从文件中读取数据并反序列化
func decode() *Address {
file, _ := os.Open(filePath)
defer file.Close()
var pa Address
//decode操作
dec := gob.NewDecoder(file)
dec.Decode(&pa)
return &pa
}