栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Go语言

【翻译】Go语言标准库学习中的encoding/gob——Go语言Gob流的管理

Go语言 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

编码

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

  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 main

import (
	"bytes"
	"encoding/gob"
	"fmt"
	"log"
)

type P struct {
	X, Y, Z int
	Name    string
}
type Q struct {
	X, Y *int32
	Name 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 Q
	err = 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:codego_projectstudyencodinggob> go run .
"Pythagoras": {3, 4}
"Treehouse": {1782, 1841}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/906169.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号