本文主要介绍二进制协议gob及msgpack的基本使用。
最近在写一个gin框架的session服务时遇到了一个问题,Go语言中的json包在序列化空接口存放的数字类型(整型、浮点型等)都序列化成float64类型。
我们构造一个结构体如下:

  1. type s struct {
  2. data map[string]interface{}
  3. }

json序列化的问题

  1. func jsonDemo() {
  2. var s1 = s{
  3. data: make(map[string]interface{}, 8),
  4. }
  5. s1.data["count"] = 1
  6. ret, err := json.Marshal(s1.data)
  7. if err != nil {
  8. fmt.Println("marshal failed", err)
  9. }
  10. fmt.Printf("%#v\n", string(ret))
  11. var s2 = s{
  12. data: make(map[string]interface{}, 8),
  13. }
  14. err = json.Unmarshal(ret, &s2.data)
  15. if err != nil {
  16. fmt.Println("unmarshal failed", err)
  17. }
  18. fmt.Println(s2)
  19. for _, v := range s2.data {
  20. fmt.Printf("value:%v, type:%T\n", v, v)
  21. }
  22. }

输出结果:

  1. "{\"count\":1}"
  2. {map[count:1]}
  3. value:1, type:float64

gob序列化示例

标准库gob是golang提供的“私有”的编解码方式,它的效率会比json,xml等更高,特别适合在Go语言程序间传递数据。

  1. func gobDemo() {
  2. var s1 = s{
  3. data: make(map[string]interface{}, 8),
  4. }
  5. s1.data["count"] = 1
  6. // encode
  7. buf := new(bytes.Buffer)
  8. enc := gob.NewEncoder(buf)
  9. err := enc.Encode(s1.data)
  10. if err != nil {
  11. fmt.Println("gob encode failed, err:", err)
  12. return
  13. }
  14. b := buf.Bytes()
  15. fmt.Println(b)
  16. var s2 = s{
  17. data: make(map[string]interface{}, 8),
  18. }
  19. // decode
  20. dec := gob.NewDecoder(bytes.NewBuffer(b))
  21. err = dec.Decode(&s2.data)
  22. if err != nil {
  23. fmt.Println("gob decode failed, err", err)
  24. return
  25. }
  26. fmt.Println(s2.data)
  27. for _, v := range s2.data {
  28. fmt.Printf("value:%v, type:%T\n", v, v)
  29. }
  30. }

msgpack

MessagePack是一种高效的二进制序列化格式。它允许你在多种语言(如JSON)之间交换数据。但它更快更小。

安装

  1. go get -u github.com/vmihailenco/msgpack

示例

  1. package main
  2. import (
  3. "fmt"
  4. "github.com/vmihailenco/msgpack"
  5. )
  6. // msgpack demo
  7. type Person struct {
  8. Name string
  9. Age int
  10. Gender string
  11. }
  12. func main() {
  13. p1 := Person{
  14. Name: "沙河娜扎",
  15. Age: 18,
  16. Gender: "男",
  17. }
  18. // marshal
  19. b, err := msgpack.Marshal(p1)
  20. if err != nil {
  21. fmt.Printf("msgpack marshal failed,err:%v", err)
  22. return
  23. }
  24. // unmarshal
  25. var p2 Person
  26. err = msgpack.Unmarshal(b, &p2)
  27. if err != nil {
  28. fmt.Printf("msgpack unmarshal failed,err:%v", err)
  29. return
  30. }
  31. fmt.Printf("p2:%#v\n", p2) // p2:main.Person{Name:"沙河娜扎", Age:18, Gender:"男"}
  32. }