【翻译】Go语言标准库学习中的encoding/gob——Go语言Gob流的管理
原文
encoding/gob in the learning of Go language standard library – the management of Go language Gob flow
根据实际情况对原文进行调整
正文
Gob 包用于管理 gob 流。它可以在编码器(发送器)和解码器(接收器)之间发送二进制数据流。一般用于传递远程程序调用的参数和结果。例如,net/rpc 包对此很有用。下面我们来学习一下gob标准库的使用,希望对你有所帮助。
主要功能介绍
gob 和 json 的打包方法一样。发送方使用 Encoder 对数据结构进行编码。接收方接收到消息后,使用解码器将序列化后的数据转化为局部变量。与json编码格式相比,gob编码可以实现json不支持的struct方法的序列化。使用 gob 包将结构体序列化并保存在本地也非常方便。
编码
数据将在传输前进行编码。与编码相关的三种方法:
- NewDecoder:
func NewEncoder(w io.Writer) *Encoder
,NewEncode 返回一个 Encoder 类型的指针,该指针将编码的数据写入 w 中 - Encode:
func (enc *Encoder) Encode(e interface{}) error
,Encode 方法编码在发送前对 e 进行编码,并且确保所有类型的信息首先发送 - EncodeValue:
func (enc *Encoder) EncodeValue(value reflect.Value) error
,EncodeValue 方法编码和发送值代表的数据,并且确保所有类型的信息首先发送
解码
接收到数据后,需要对数据进行解码。
- NewDecoder:
func NewDecoder(r io.Reader) *Decoder
,该方法染回一个从 r 中读取数据的解码器,如果 r 不满足io.ByteReader
类型,接口将会将 r 包裹成bufio.Reader
类型 - Decode:
func (dec *Decoder) Decode(e interface{}) error
- 解码从输入流中读取下一个并将值存储在 e 中。
- 如果 e 是
nil
,则该值会被遗弃,否则 e 将会是一个可以接收该类型值的指针。 - 如果输入结束了,这个方法返回一个
io.EOF
并且不会改变 e(指向的值)
- DecodeValue:
func (dec *Decoder) DecodeValue(v reflect.Value) error
- DecodeValue 从输入流中读取下一个值,如果 V 是 reflect.Value 类型的零值(v.Kind() == Invalid)则被丢弃,否则这个值存放在 V 中。
- 在这种情况下,V 代表了一个指向实际值的非零指针,或者一个可写的 reflect.Value 类型(v.CanSet() 为真)
- 如果输入结束了,这个方法返回一个
io.EOF
并且不会改变 e(指向的值)
gob 编码的优点与局限
局限
这里需要明确一下,gob只能在golang中使用。因此,在实际的项目开发过程中,如果与其他终端或其他语言打交道,gob是不允许的。我们将使用 json。
优势
Gob 流是自解码的。流中的所有数据都带有前缀(在预定义类型的集合中)以指示其类型。指针不传递,而是传递值;也就是说,数据被扁平化。递归类型可以很好的工作,但递归值(例如,值中的成员直接/间接指向该值)可能会出错。这个问题将来可能会得到解决。
要使用 gob,您首先创建一个编码器并为其提供一系列数据:一个值或指向实际数据的指针。编码器确保发送所有必要的类型信息。在接收端,解码器从编码数据流中恢复数据并将其填充到局部变量中。
gob 编码和解码不需要发送器和接收器的结构相同。以下是官方文件的翻译:
// 定义一个结构体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 字段会被忽略;数据会被遗弃struct { B, C int } // 缺少的 A 字段会被忽略; 多余的 C 字段会被忽略.// 以下格式有问题:struct { A int; B uint } // B 的签名改变了struct { A int; B float } // B 的类型改变了struct { } // 没有共同的字段名struct { C, D int } // 没有共同的字段名
译者注:总而言之解码和编码相匹配就是遵循以下几个标准
- 存在指针可以(不论是结构体指针,还是字段指针),go 提供了自动解指针的能力
- 缺少或者存在额外字段可以,但是至少(发送和接收的)结构中存在一个相匹配的字段
gob 编码实例
这里以官网 https://golang.org/pkg/encoding/gob/ 为例:
基础
package mainimport ("bytes""encoding/gob""fmt""log"
)type P struct {X, Y, Z intName string
}
type Q struct {X, Y *int32Name string
}// 这是一个基础的创建编码器的用例,编码数据,然后用解码器来接收
func main() {// 初始化编码器,并且创建一个解码器的实例var network bytes.Buffer // 标准输入enc := gob.NewEncoder(&network) // 编码dec := gob.NewDecoder(&network) // 解码// 编码器发送数据err := enc.Encode(P{3, 4, 5, "Pythagoras"})if err != nil {log.Fatal("encode error:", err)}err = enc.Encode(P{1782, 1841, 1922, "Treehouse"})if err != nil {log.Fatal("encode error:", err)}// 解码器接收数据var q Qerr = dec.Decode(&q)if err != nil {log.Fatal("decode error 1:", err)}fmt.Printf("%q: {%d, %d}\n", q.Name, *q.X, *q.Y)err = dec.Decode(&q)if err != nil {log.Fatal("decode error 2:", err)}fmt.Printf("%q: {%d, %d}\n", q.Name, *q.X, *q.Y)
}
译者图
控制台
PS D:\code\go_project\study\encoding\gob> go run .
"Pythagoras": {3, 4}
"Treehouse": {1782, 1841}
【翻译】Go语言标准库学习中的encoding/gob——Go语言Gob流的管理相关推荐
- C++语言标准库functional中的函数对象,绝对是装B神器~
C++语言标准库<functional>中的函数对象,绝对是装B神器~用一下,感慨万千~~~ 基本上是C++ Primer上的,show一下代码: #include <iostrea ...
- Go语言标准库学习之encoding/gob——Go语言Gob流的管理
gob包是用来管理gob流的,它可以实现在编码器(发送器)和解码器(接收器)之间进行二进制数据流的发送,一般用来传递远端程序调用的参数和结果,比如net/rpc包就有用到这个.下面我们来学习以下gob ...
- 【C/C++基础】C语言标准库
C语言标准库 C89中 文件 简介说明 <assert.h> 断言相关 <ctype.h> 字符类型判断 <errno.h> 标准报错机制 <float.h& ...
- python语言学习:python语言学习中的定义类、定义函数、封装api等详细攻略
python语言学习:python语言学习中的定义类.定义函数.封装api等详细攻略 目录 python语言学习中的定义类 python语言学习中的定义函数 python语言学习中封装api pyth ...
- c语言补码计算方法,探讨C语言学习中补码计算方法.doc
探讨C语言学习中补码计算方法 探讨C语言学习中补码计算方法 摘要:补码是C语言学习中的一个重点和难点,如何能够快速准确地计算出各个数的补码值得我们探讨.本文从补码的意义入手,采用逆向逻辑思维,分别提出 ...
- Go 语言标准库中 atomic.Value
在 Go 语言标准库中,sync/atomic包将底层硬件提供的原子操作封装成了 Go 的函数.但这些操作只支持几种基本数据类型,因此为了扩大原子操作的适用范围,Go 语言在 1.4 版本的时候向sy ...
- mysql c语言数字转字符串函数_C++_c语言标准库中字符转换函数和数字转换函数,字符转换为数字:
#includest - phpStudy...
c语言标准库中字符转换函数和数字转换函数 字符转换为数字: #include atoi();将字符转换为整型 例:char ch1;int i=atoi(ch1); atol();将字符转化为长整 ...
- Linux中C语言标准库glibc源码下载
在这篇文章理清gcc.libc.glibc.libc++.libstdc++的关系,我们大概理解了libc,glibc之间的一些关系. 下面我们就开了解一些Linux中C语言标准库glibc源码. 在 ...
- 强化学习中的episode如何理解和翻译?
1. episode的感性理解 强化学习中,episode是个重要的术语.那么episode应该如何理解呢? An episode is one complete play of the agent ...
最新文章
- Struts原理与实践(5)
- 栏目图片 栏目描述_昕街拍|长期福利栏目来啦,秀街拍赢礼品!
- AT2064-[AGC005F]Many Easy Problems【NTT】
- 由c语言转向c++,我们需要做什么?
- 【推荐】(SqlServer)不公开存储过程sp_Msforeachtable与sp_Msforeachdb详解
- 导购效果跟踪: SPM
- 耳机的L和R是什么意思?
- Redis 存储SQL表格 方法
- 从0开始运行flutter helloworld笔记
- 计算混响时间的意义_混响是什么意思,混响时间计算公式汇总,混响器的
- linux 安装mysql(rpm文件安装)
- Redis持久化策略AOF、RDB详解及源码分析
- GAN-cls:具有匹配感知的判别器
- Java8增加功能--Effectively final 功能
- php think命令,ThinkPHP 使用命令行 (cli) think 调用
- 【并发编程系列6】Condition队列原理及await和singal(等待/唤醒)机制源码分析
- html攻击代码,利用HTML5标签进行DDoS攻击的新方法揭秘
- 约束优化问题的一阶条件(KKT条件)、互补松弛条件、拉格朗日对偶问题、SVM
- 加拿大FBA海运详细说明
- PTA练习:谁先倒.(C语言)