共计 2663 个字符,预计需要花费 7 分钟才能阅读完成。
留神到 encoding/gob
包是因为看到 net/rpc
包应用它编解码。
二者都是规范库下的包。
一、示例代码和执行后果
// hello.go
package main
import (
"bytes"
"encoding/gob"
"fmt"
)
type Request struct {
ServiceMethod string // format: "Service.Method"
Seq uint64 // sequence number chosen by client
next *Request // for free list in Server
}
type Request3 struct {ServiceMethod string}
type Request4 struct {Other int64}
func main() {
var err error
a := &bytes.Buffer{}
encoder := gob.NewEncoder(a)
_ = encoder.Encode(&Request{
Seq: 23,
ServiceMethod: "firstMethod",
})
_ = encoder.Encode(&Request{
Seq: 9,
ServiceMethod: "secondMethod",
})
_ = encoder.Encode(&Request{
Seq: 16,
ServiceMethod: "thirdMethod",
})
_ = encoder.Encode(&Request{
Seq: 77,
ServiceMethod: "fourthMethod",
})
fmt.Printf("buf: %#v\n\n", a)
b := bytes.NewBufferString(a.String())
decoder := gob.NewDecoder(b)
ans1 := &Request{}
_ = decoder.Decode(ans1)
fmt.Println("ans1 err:", err)
fmt.Printf("ans1: %#v\n\n", ans1)
ans2 := &Request{}
err = decoder.Decode(ans2)
fmt.Println("ans2 err:", err)
fmt.Printf("ans2: %#v\n\n", ans2)
ans3 := &Request3{}
err = decoder.Decode(ans3)
fmt.Println("ans3 err:", err)
fmt.Printf("ans3: %#v\n\n", ans3)
ans4 := &Request4{}
err = decoder.Decode(ans4)
fmt.Println("ans4 err:", err)
fmt.Printf("ans4: %#v\n\n", ans4)
ans5 := &Request{}
err = decoder.Decode(ans5)
fmt.Println("ans5 err:", err)
fmt.Printf("ans5: %#v\n\n", ans5)
}
$ go run ./hello.go
buf: &bytes.Buffer{buf:[]uint8{0x2f, 0xff, 0x81, 0x3, 0x1, 0x1, 0x7, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1, 0xff, 0x82, 0x0, 0x1, 0x2, 0x1, 0xd, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x1, 0xc, 0x0, 0x1, 0x3, 0x53, 0x65, 0x71, 0x1, 0x6, 0x0, 0x0, 0x0, 0x12, 0xff, 0x82, 0x1, 0xb, 0x66, 0x69, 0x72, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x1, 0x17, 0x0, 0x13, 0xff, 0x82, 0x1, 0xc, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x1, 0x9, 0x0, 0x12, 0xff, 0x82, 0x1, 0xb, 0x74, 0x68, 0x69, 0x72, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x1, 0x10, 0x0, 0x13, 0xff, 0x82, 0x1, 0xc, 0x66, 0x6f, 0x75, 0x72, 0x74, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x1, 0x4d, 0x0}, off:0, lastRead:0}
ans1 err: <nil>
ans1: &main.Request{ServiceMethod:"firstMethod", Seq:0x17, next:(*main.Request)(nil)}
ans2 err: <nil>
ans2: &main.Request{ServiceMethod:"secondMethod", Seq:0x9, next:(*main.Request)(nil)}
ans3 err: <nil>
ans3: &main.Request3{ServiceMethod:"thirdMethod"}
ans4 err: gob: type mismatch: no fields matched compiling decoder for Request4
ans4: &main.Request4{Other:0}
ans5 err: EOF
ans5: &main.Request{ServiceMethod:"", Seq:0x0, next:(*main.Request)(nil)}
二、解读
以上代码一次性编码写入 4 条数据,分 5 次读取、解码。
- ans1、ans2 能正确解读,阐明
gob
能精确辨认边界; - ans3 能正确解读,
gob
解码的时候不在乎构造具体叫什么,但在乎其中的具体字段; - ans4 解读提醒
type mismatch
,阐明想要精确解读须要数据写入方、读取方彼此协调好,应用雷同的数据结构; - ans5 传入的数据结构能对应上第 4 条输出,但没能解读到数据,提醒
EOF
,阐明 ans4 尽管没能精确解读,但应用了gob
解码须要的信息。
综合以上,能够演绎 gob
应用的特点
1、可先不读取解码,一次性多条编码写入;
2、读取解码时,可自动识别每一条信息的边界;
3、每次读取解码时,先取出一条编码信息,再同传入的指定构造匹配并填充,失败时数据不会放回;
4、解码时发现没有数据,报错 EOF
。
另:编、解码传入的指定构造都须要是指针类型。
正文完