原文

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 包将结构体序列化并保存在本地也非常方便。

编码

数据将在传输前进行编码。与编码相关的三种方法:

  1. NewDecoder:func NewEncoder(w io.Writer) *Encoder,NewEncode 返回一个 Encoder 类型的指针,该指针将编码的数据写入 w 中
  2. Encode:func (enc *Encoder) Encode(e interface{}) error,Encode 方法编码在发送前对 e 进行编码,并且确保所有类型的信息首先发送
  3. EncodeValue:func (enc *Encoder) EncodeValue(value reflect.Value) error,EncodeValue 方法编码和发送值代表的数据,并且确保所有类型的信息首先发送

解码

接收到数据后,需要对数据进行解码。

  1. NewDecoder:func NewDecoder(r io.Reader) *Decoder,该方法染回一个从 r 中读取数据的解码器,如果 r 不满足 io.ByteReader类型,接口将会将 r 包裹成 bufio.Reader类型
  2. Decode:func (dec *Decoder) Decode(e interface{}) error
    • 解码从输入流中读取下一个并将值存储在 e 中。
    • 如果 e 是 nil,则该值会被遗弃,否则 e 将会是一个可以接收该类型值的指针。
    • 如果输入结束了,这个方法返回一个 io.EOF并且不会改变 e(指向的值)
  3. 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 }      // 没有共同的字段名

译者注:总而言之解码和编码相匹配就是遵循以下几个标准

  1. 存在指针可以(不论是结构体指针,还是字段指针),go 提供了自动解指针的能力
  2. 缺少或者存在额外字段可以,但是至少(发送和接收的)结构中存在一个相匹配的字段

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流的管理相关推荐

  1. C++语言标准库functional中的函数对象,绝对是装B神器~

    C++语言标准库<functional>中的函数对象,绝对是装B神器~用一下,感慨万千~~~ 基本上是C++ Primer上的,show一下代码: #include <iostrea ...

  2. Go语言标准库学习之encoding/gob——Go语言Gob流的管理

    gob包是用来管理gob流的,它可以实现在编码器(发送器)和解码器(接收器)之间进行二进制数据流的发送,一般用来传递远端程序调用的参数和结果,比如net/rpc包就有用到这个.下面我们来学习以下gob ...

  3. 【C/C++基础】C语言标准库

    C语言标准库 C89中 文件 简介说明 <assert.h> 断言相关 <ctype.h> 字符类型判断 <errno.h> 标准报错机制 <float.h& ...

  4. python语言学习:python语言学习中的定义类、定义函数、封装api等详细攻略

    python语言学习:python语言学习中的定义类.定义函数.封装api等详细攻略 目录 python语言学习中的定义类 python语言学习中的定义函数 python语言学习中封装api pyth ...

  5. c语言补码计算方法,探讨C语言学习中补码计算方法.doc

    探讨C语言学习中补码计算方法 探讨C语言学习中补码计算方法 摘要:补码是C语言学习中的一个重点和难点,如何能够快速准确地计算出各个数的补码值得我们探讨.本文从补码的意义入手,采用逆向逻辑思维,分别提出 ...

  6. Go 语言标准库中 atomic.Value

    在 Go 语言标准库中,sync/atomic包将底层硬件提供的原子操作封装成了 Go 的函数.但这些操作只支持几种基本数据类型,因此为了扩大原子操作的适用范围,Go 语言在 1.4 版本的时候向sy ...

  7. mysql c语言数字转字符串函数_C++_c语言标准库中字符转换函数和数字转换函数,字符转换为数字: #includest - phpStudy...

    c语言标准库中字符转换函数和数字转换函数 字符转换为数字: #include atoi();将字符转换为整型   例:char ch1;int i=atoi(ch1); atol();将字符转化为长整 ...

  8. Linux中C语言标准库glibc源码下载

    在这篇文章理清gcc.libc.glibc.libc++.libstdc++的关系,我们大概理解了libc,glibc之间的一些关系. 下面我们就开了解一些Linux中C语言标准库glibc源码. 在 ...

  9. 强化学习中的episode如何理解和翻译?

    1. episode的感性理解 强化学习中,episode是个重要的术语.那么episode应该如何理解呢? An episode is one complete play of the agent ...

最新文章

  1. Struts原理与实践(5)
  2. 栏目图片 栏目描述_昕街拍|长期福利栏目来啦,秀街拍赢礼品!
  3. AT2064-[AGC005F]Many Easy Problems【NTT】
  4. 由c语言转向c++,我们需要做什么?
  5. 【推荐】(SqlServer)不公开存储过程sp_Msforeachtable与sp_Msforeachdb详解
  6. 导购效果跟踪: SPM
  7. 耳机的L和R是什么意思?
  8. Redis 存储SQL表格 方法
  9. 从0开始运行flutter helloworld笔记
  10. 计算混响时间的意义_混响是什么意思,混响时间计算公式汇总,混响器的
  11. linux 安装mysql(rpm文件安装)
  12. Redis持久化策略AOF、RDB详解及源码分析
  13. GAN-cls:具有匹配感知的判别器
  14. Java8增加功能--Effectively final 功能
  15. php think命令,ThinkPHP 使用命令行 (cli) think 调用
  16. 【并发编程系列6】Condition队列原理及await和singal(等待/唤醒)机制源码分析
  17. html攻击代码,利用HTML5标签进行DDoS攻击的新方法揭秘
  18. 约束优化问题的一阶条件(KKT条件)、互补松弛条件、拉格朗日对偶问题、SVM
  19. 加拿大FBA海运详细说明
  20. PTA练习:谁先倒.(C语言)

热门文章

  1. 深入理解ForkJoin及使用示例
  2. 驱动 EPSON TM-U220PDmodel m188d ATM 301gSC 下载
  3. high sierra镜像_在High Sierra升级后修复git
  4. 采用WTL及LibXML2进行传真软件的开发
  5. 教务辅助管理系统mysql_数据库程序设计---教务辅助管理系统.doc
  6. CAS server打包小白教程
  7. STM32F4+VL530L0x激光测距cubemx实现
  8. @Qualifier注解作用
  9. jointjs -- link
  10. 不透明度 16进制值