本文主要介绍二进制协议gob及msgpack的基本使用。
Go语言中的json包在序列化空接口存放的数字类型(整型、浮点型等)都序列化成float64类型。
Json
从下面的例子就可以看出 json 序列化的时候会将空接口存放的数字类型(整型、浮点型等)都序列化成float64类型。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24func jsonDemo() {
test1 := map[string]interface{}{
"count": 1,
}
data1, err := json.Marshal(test1)
if err != nil {
log.Fatal(err)
return
}
fmt.Println(data1)
test2 := make(map[string]interface{})
if err := json.Unmarshal(data1, &test2); err != nil {
log.Fatal(err)
return
}
for _, v := range test2 {
fmt.Printf("value : %v, type = %T\n", v, v)
}
}输出的结果为:
可以看出原本 int 类型的 interface{} 被转化成为了 float64
1
2[123 34 99 111 117 110 116 34 58 49 125]
value : 1, type = float64
Gob
标准库gob是golang提供的“私有”的编解码方式,它的效率会比json,xml等更高,特别适合在Go语言程序间传递数据。
但是它序列化之后的结果会比json要大一些
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26func gobDemo() {
test1 := map[string]interface{}{
"count": int64(12),
}
// encode
buf := new(bytes.Buffer)
enc := gob.NewEncoder(buf)
err := enc.Encode(test1)
if err != nil {
log.Fatal(err)
}
b := buf.Bytes()
fmt.Println(b)
test2 := make(map[string]interface{})
dec := gob.NewDecoder(bytes.NewBuffer(b))
err = dec.Decode(&test2)
if err != nil {
log.Fatal(err)
}
for _, v := range test2 {
fmt.Printf("value : %v, type = %T\n", v, v)
}
}输出的结果为:
1
2[14 255 129 4 1 2 255 130 0 1 12 1 16 0 0 20 255 130 0 1 5 99 111 117 110 116 5 105 110 116 54 52 4 2 0 24]
value : 12, type = int64
使用gob的一些特殊情况
- 在使用gob序列化一些特殊的数据结构(例如:[]interface{})的时候,使用前需要先注册,使用的时候需要特别注意这一点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28package main
import (
"bytes"
"encoding/gob"
"fmt"
"log"
)
func main() {
// 如果这一行被注释掉,程序会崩溃
// gob.Register([]interface{}{})
input := map[string]interface{}{"X": []interface{}{1, 2}}
buff := new(bytes.Buffer)
enc := gob.NewEncoder(buff)
if err := enc.Encode(input); err != nil {
log.Panic("e1: ", err)
}
b1 := buff.Bytes()
output := map[string]interface{}{}
if err := gob.NewDecoder(bytes.NewReader(b1)).Decode(&output); err != nil {
log.Panic("e2: ", err)
}
fmt.Println(output)
}
MsgPack
- MessagePack是一种高效的二进制序列化格式。它允许你在多种语言(如JSON)之间交换数据。但它更快更小。
- 它和json存在类似的问题就是 序列化的时候会将空接口存放的 int都序列化成 int64 类型。
安装
1
go get -u github.com/vmihailenco/msgpack
示例
1 | package main |
- 输出结果如下:
1
2[129 165 99 111 117 110 116 211 0 0 0 0 0 0 0 1]
value : 1, type = int64
总结
- json序列化空接口存放的数字类型(整型、浮点型等)都序列化成float64类型。
- msgpack序列化空接口存放的 int 都序列化成 int64 类型。
- 从序列化之后的体积来看 msgpack < json < gob, 但是gob对于 空接口interface{} 的数据类型有比较好的复原
- 使用建议:在不涉及interface{}的情况下,使用体积较小的,如果使用了interface{}并且对数据类型要求较高的情况下,推荐使用gob