gob是Golang包自带的一个数据结构序列化的编码/解码工具。编码使用Encoder,解码使用Decoder。一种典型的应用场景就是RPC(remote procedure calls)。

gob和json的pack之类的方法一样,由发送端使用Encoder对数据结构进行编码。在接收端收到消息之后,接收端使用Decoder将序列化的数据变化成本地变量。

  • 基本使用

package mainimport ("bytes""encoding/gob""fmt"
)type MsgData struct {X, Y, Z intName string
}
var network bytes.Buffer //网络传递的数据载体
func main() {err := senMsg()if err!=nil {fmt.Println("编码错误")return}err = revMsg()if err!=nil {fmt.Println("解码错误")return}
}func senMsg()error {fmt.Print("开始执行编码(发送端)")enc := gob.NewEncoder(&network)sendMsg:=MsgData{3, 4, 5, "jiangzhou"}fmt.Println("原始数据:",sendMsg)err := enc.Encode(&sendMsg)fmt.Println("传递的编码数据为:",network)return  err
}
func revMsg()error {var revData MsgDatadec:=gob.NewDecoder(&network)err:= dec.Decode(&revData) //传递参数必须为 地址fmt.Println("解码之后的数据为:",revData)return err
}

Register和RegisterName

  1. 编码的数据中有空接口类型,传递时赋值的空接口为:基本类型(int、float、string)、切片时,可以不进行注册。
package mainimport ("bytes""encoding/gob""fmt"
)type MsgData struct {X, Y, Z intName stringMsg interface{}
}
var network bytes.Buffer //网络传递的数据载体
func main() {err := senMsg()if err!=nil {fmt.Println("编码错误")return}err = revMsg()if err!=nil {fmt.Println("解码错误")return}
}func senMsg()error {fmt.Print("开始执行编码(发送端)")enc := gob.NewEncoder(&network)s:=make([]string,0)s=append(s, "hello")//sendMsg:=MsgData{3, 4, 5, "jiangzhou",Msg{10001,"hello"}}//sendMsg:=MsgData{3, 4, 5, "jiangzhou",66.66}sendMsg:=MsgData{3, 4, 5, "jiangzhou",s}fmt.Println("原始数据:",sendMsg)err := enc.Encode(&sendMsg)fmt.Println("传递的编码数据为:",network)return  err
}
func revMsg()error {var revData MsgDatadec:=gob.NewDecoder(&network)err:= dec.Decode(&revData) //传递参数必须为 地址fmt.Println("解码之后的数据为:",revData)return err
}

编码的数据中有空接口类型,传递时赋值的空接口为:map、struct时,必须进行注册。

package mainimport ("bytes""encoding/gob""fmt"
)type MsgData struct {X, Y, Z intName stringMsg interface{}
}
var network bytes.Buffer //网络传递的数据载体
func main() {err := senMsg()if err!=nil {fmt.Println("编码错误")return}err = revMsg()if err!=nil {fmt.Println("解码错误")return}
}func senMsg()error {fmt.Print("开始执行编码(发送端)")enc := gob.NewEncoder(&network)m:=make(map[int]string)m[10001]="hello"m[10002]="jiangzhou"sendMsg:=MsgData{3, 4, 5, "jiangzhou",m}fmt.Println("原始数据:",sendMsg)err := enc.Encode(&sendMsg)fmt.Println("传递的编码数据为:",network)return  err
}
func revMsg()error {var revData MsgDatadec:=gob.NewDecoder(&network)err:= dec.Decode(&revData) //传递参数必须为 地址fmt.Println("解码之后的数据为:",revData)return err
}

Register和RegisterName解决的主要问题是:当编解码中有一个字段是interface{}(interface{}的赋值为map、结构体时)的时候需要对interface{}的可能产生的类型进行注册。

正确代码为:

interface{}的赋值为map时:

package mainimport ("bytes""encoding/gob""fmt"
)type MsgData struct {X, Y, Z intName stringMsg interface{}
}
var network bytes.Buffer //网络传递的数据载体
func main() {err := senMsg()if err!=nil {fmt.Println("编码错误")return}err = revMsg()if err!=nil {fmt.Println("解码错误")return}
}func senMsg()error {fmt.Print("开始执行编码(发送端)")enc := gob.NewEncoder(&network)m:=make(map[int]string)m[10001]="hello"m[10002]="jiangzhou"gob.Register(map[int]string{}) //TODO:进行了注册sendMsg:=MsgData{3, 4, 5, "jiangzhou",m}fmt.Println("原始数据:",sendMsg)err := enc.Encode(&sendMsg)fmt.Println("传递的编码数据为:",network)return  err
}
func revMsg()error {var revData MsgDatadec:=gob.NewDecoder(&network)err:= dec.Decode(&revData) //传递参数必须为 地址fmt.Println("解码之后的数据为:",revData)return err
}

interface{}的赋值为结构体时:

package mainimport ("bytes""encoding/gob""fmt"
)type MsgData struct {X, Y, Z intName    stringMsg     interface{}
}var network bytes.Buffer //网络传递的数据载体
func main() {err := senMsg()if err != nil {fmt.Println("编码错误",err)return}err = revMsg()if err != nil {fmt.Println("解码错误")return}
}type Msg struct {Id     intDetail string
}func senMsg() error {fmt.Print("开始执行编码(发送端)")enc := gob.NewEncoder(&network)gob.Register(Msg{}) //TODO:进行了注册s:=Msg{10001,"hello jiangzhou"}sendMsg := MsgData{3, 4, 5, "jiangzhou", s}fmt.Println("原始数据:", sendMsg)err := enc.Encode(&sendMsg)fmt.Println("传递的编码数据为:", network)return err
}
func revMsg() error {var revData MsgDatadec := gob.NewDecoder(&network)err := dec.Decode(&revData) //传递参数必须为 地址fmt.Println("解码之后的数据为:", revData)return err
}

注:特别注意:以上代码中的结构体Msg对应的成员变量名称首字母一定要大写,不然会出现:编码错误编码错误 gob: type main.Msg has no exported fields

这里使用了

gob.Register(Msg{})

告诉系统:所有的Interface是有可能为Msg结构的。

在这个例子中,如果你注释了gob.Register, 系统会报错。

RegisterName是和Register一样的效果,只是在Register的同时也为这个类型附上一个别名。

➢了解更多Go语言知识:https://study.163.com/course/introduction/1210620804.htm

Golang Gob编码(gob包的使用)相关推荐

  1. Golang Gob编码

    2019独角兽企业重金招聘Python工程师标准>>> gob是Golang包自带的一个数据结构序列化的编码/解码工具.编码使用Encoder,解码使用Decoder.一种典型的应用 ...

  2. Go : 基准测试gob编码和解码性能(附完整源码)

    Go : 基准测试gob编码和解码性能 package go1 import ("bytes""encoding/gob""encoding/json ...

  3. golang 解决 TCP 粘包问题

    什么是 TCP 粘包问题以及为什么会产生 TCP 粘包,本文不加讨论.本文使用 golang 的 bufio.Scanner 来实现自定义协议解包. 协议数据包定义 本文模拟一个日志服务器,该服务器接 ...

  4. golang解决TCP粘包问题

    6行代码解决golang TCP粘包 转自:https://studygolang.com/articles/12483 什么是TCP粘包问题以及为什么会产生TCP粘包,本文不加讨论.本文使用gola ...

  5. Golang Base64编码解码

    Golang Base64编码解码 Golang内置支持Base64编码解码,Go的encoding/base64包遵照RFC 4648规范实现了base64编码解码功能,包括标准方式以及URL/文件 ...

  6. 【ReactiveX】基于Golang pmlpml/RxGo程序包的二次开发

    基于Golang pmlpml/RxGo程序包的二次开发[阅读时间:约20分钟] 一.ReactiveX & RxGo介绍 1.ReactiveX 2.RxGo 二.系统环境&项目介绍 ...

  7. golang中container/list包中的坑

    转载地址:golang中container/list包中的坑 - Go语言中文网 - Golang中文社区 golang中list包用法可以参看golang中container/list包用法_che ...

  8. golang中os/signal包的使用

    golang中os/signal包的使用 os/signal包实现对信号的处理 golang中对信号的处理主要使用os/signal包中的两个方法:一个是notify方法用来监听收到的信号:一个是 s ...

  9. Go (Golang) 工具之依赖包管理工具goimports | Go语言规范-import规范(导入)排序 |GoLand:设置gofmt与goimports,保存时自动格式化代码

    文章目录 Go (Golang) 工具之依赖包管理工具goimports Go语言规范-import(导入)排序 什么是goimports 安装和使用 Golang 使用goimports unrec ...

最新文章

  1. 2019编程语言最新排行榜!Python蝉联第一
  2. 银行柜台基金买卖现长龙 业内支招宜用新方式
  3. 主席树 | 莫队 ---- Codeforces Round #716 (Div. 2) D. Cut and Stick [主席树or莫队优化] 区间众数问题(静态)
  4. 有关于mfc webbrowser插件的使用
  5. Maven2整合集成IntelliJ IDEA创建Web项目
  6. 深入浅出python机器学习_9.1_数据预处理_sklearn.preprocessing.StandardScaler MinMaxScaler RobustScaler Normalizer
  7. 最新进展 | 深度学习在天气预测中的应用
  8. ef6 mysql_VS2015 + EF6连接MYSQL5.6
  9. layuiajax提交表单控制层代码_Ninja Forms:免费的联系表单插件,却提供了付费表单才有的功能【视频+图文】...
  10. 多级联动下拉java,下拉列表多级联动前端实现
  11. 地级市面板数据一(2000-2019):国民经济核算+人口结构+各行业从业人员(stata版)
  12. java植物大战僵尸_JAVA课程设计——植物大战僵尸(团队)
  13. 学海无涯!腾讯、网易必问的20道题Android面试题,已拿offer入职
  14. STM8S105S4T6C和STM8S105C6T6对比
  15. Whale帷幄 - 门面的力量丨提升进店客流
  16. 线上活动| 阿里云、亚马逊云与MongoDB的技术专家带你来涨知识
  17. leetcode:递增的三元子序列
  18. 大量数据进行数组操作的Redim Preserve替代方法
  19. Linux安装Apache环境(有图有真相!)
  20. Android开发:Android颜色透明度换算表

热门文章

  1. source insight项目导入和使用教程
  2. Cyberbit:某国际机场一半以上工作站都已被挖矿软件占领
  3. 在Latex使用條列式清單itemize , enumerate , description [转]
  4. redis实战(5):对文章进行分组
  5. 王者服务器维护公告2月,王者天下2月17日服务器调整公告
  6. Flex是咋回事之一 集CS和BS之大成的RIA
  7. 正则表达式:一张图入门级了解正则表达式
  8. layerui ios不适应问题
  9. Navicat数据库管理工具【免费试用14天】试用攻略
  10. ajax 同步和异步区别