gob包("encoding/gob")管理gob流——在encoder(编码器,也就是发送器)和decoder(解码器,也就是接受器)之间交换的字节流数据(gob 就是 go binary的缩写)。一般用于传递远端程序调用(RPC)的参数和结果。

要使用gob,要先创建一个编码器(调用NewEncoder()方法),并向其提供一系列数据;然后在接收端,通过调用NewDecoder()方法创建一个解码器,它从数据流中恢复数据并将它们填写进本地变量里。下面会通过几个例子进行说明。

发送端和接收端的值/类型不需要严格匹配。对结构体来说,某一字段(通过字段名进行识别)如果发送端有而接收端没有,会被忽略;接收端有而发送端没有的字段也会被忽略;发送端和接收端都有的字段其类型必须是可兼容的;发送端和接收端都会在gob流和实际go类型之间进行必要的指针取址/寻址工作。举例如下:

下面是发送端的承载数据的结构体:
struct { A, B int }
可以和如下类型互相发送和接收:
struct { A, B int }// 同一类型
*struct { A, B int }// 结构体需要额外重定向(指针)
struct { *A, **B int }// 字段需要额外重定向(指针)
struct { A, B int64 }// 同为整型/浮点型且符号类型相同的不同值类型
可以发送给如下任一类型:
struct { A, B int }// 同一类型
struct { B, A int }// 字段顺序改变无影响,按名称匹配
struct { A, B, C int }// 忽略多出的字段C
struct { B int }// 忽略缺少的字段A,会丢弃A的值
struct { B, C int }// 忽略缺少的字段A,忽略多出的字段C
但尝试发送给如下类型的话就会导致错误:
struct { A int; B uint }// B字段改变了符号类型
struct { A int; B float }// B字段改变了类型
struct { }// 无共同字段名
struct { C, D int }// 无共同字段名

示例1:

type P struct {
   X, Y, Z int
   Name    string
}

type Q struct {
   X, Y *int32
   Name string
}

type R struct {
   Y, W int
}

// This example shows the basic usage of the package: Create an encoder,
// transmit some values, receive them with a decoder.
func GobBasic() {
   // 初始化 encoder 和 decoder
   var buf bytes.Buffer
   encoder := gob.NewEncoder(&buf) // will write to buf
   decoder := gob.NewDecoder(&buf) // will read from buf

   // Encode (send) some values
   err := encoder.Encode(P{X: 3, Y: 4, Z: 5, Name: "hello"})
   if err != nil {
      log.Fatal("Encode error:",err)
   }

   // Decode (receive) and print the values
   //var q Q
   //err = decoder.Decode(&q)
   //if err != nil {
   // log.Fatal("Decode error:",err)
   //}
   //
   //// 注意,不能写成 q.X,因为在接收方,定义的是 int型 指针
   //// *(q.X) 与 *q.Y 结果相同,但前者语义更加明确
   //fmt.Printf("%d %d %s\n", *(q.X), *q.Y, q.Name)

   //var p P
   //err = decoder.Decode(&p)
   //if err != nil {
   // log.Fatal("Decode error:",err)
   //}
   //// 这里的接收方和传入方格式完全一致
   //fmt.Printf("%d %d %d %s\n", p.X, p.Y, p.Z, p.Name)

   var r R
   err = decoder.Decode(&r)
   if err != nil {
      log.Fatal("Decode error:",err)
   }

   //fmt.Printf("%d %d %d %s\n", r.X, r.Y, r.Z, r.Name)
   // 会输出如下:因为接收端是根据字段名称进行匹配的
   // r.X undefined (type R has no field or method X)
   // r.Z undefined (type R has no field or method Z)
   // r.Name undefined (type R has no field or method Name)
   fmt.Printf("%d\n", r.Y) // ok
}
View Code

示例2:

12-30 19:08
查看更多