zoukankan      html  css  js  c++  java
  • Go Gob编码

    gob(Go binary)是Goland包自带的一个数据结构序列化的编码/解码工具。编码使用Encoder,解码使用Decoder。一种典型的应用场景就是RPC(remote procedure calls)。
    gob和json的pack之类的方法一样,由发送端使用encoder对数据结构进行编码。在接收端使用decoder将序列化的数据转成本地变量。
    Go语言可以通过JSON或Gob来序列化struct对象,虽然JSON的序列化更为通用,但利用Gob编码可以实现JSON所不能支持的struct的方法序列化,利用Gob包序列化struct保存到本地也十分简单。

    Gob编解码规则

    对于Gob而言,发送方和接收方的数据结构并不需要完全一致,官方示例为例:

    上述struct{A,B int}结构编码的数据可以被后面九种结构类型接受解码,具体来说,接受数据结构只要满足与发送数据结构签名一致(与顺序无关,类型之间不能相互编解码,整型还要细分有符号和无符号)、或者是发送数据类型的子集(但不能为空)或超集,即正常接收并解码
    具体到不同的数据类型,规则如下:

    • struct{A,B int}arrayslice是可以被编码的,但是functionchannel是不能被编码的
    • 整型分为有符号和无符号,无符号和有符号整型是不能互相编解码的
    • 布尔类型是被当做uint来编码的,0false1true
    • 浮点型的值都是被当做float64类型的值来编码的,浮点型和整型也是不能相互编码的
    • 字符串类型(包括string[]byte)是无符号字节个数+每个字节编码的形式编解码的
    • 数组类型(包括slicearray)是按照无符号元素个数+每个数组元素编码的形式进行编解码的
    • 字典类型(map)是按照无符号元素个数+键值对的形式进行编解码的
    • 结构体类型(struct)是按照序列化的属性名+属性值来进行编解码的,其中属性值是其自己对应类型的Gob编码,如果有一个属性值为0或空,则这个属性直接被忽略,每个属性的序号是编码时的顺序决定的,从0开始顺序递增。struct在序列化前会以-1代表序列化的开始,以0代表序列化的结束,即struct的序列化是按照"-1(0属性1的名字 属性1的值)(1 属性2的名字 属性2的值)"来进行编码的
      注:struct类型的属性名都应该是大写字母开头,以便可以在包外被访问

    gob包提供的API

    结构体

    type GobDecoder interface
    type GobEncoder interface
    type Decoder struct
    type Encoder struct
    

    函数列表:

    func Register(value interface{})
    func RegisterName(name string, value interface{})
    func NewDecoder(r io.Reader) *Decoder
    func (dec *Decoder) Decode(e interface{}) error
    func (dec *Decoder) DecoderValue(v reflect.Value) error
    func NewEncoder(w io.Writer) *Encoder
    func (enc *Encoder) Encode(e interface{}) error
    func (enc *Encoder) EncodeValue(value reflect.Value) error
    

    详解:
    1)GobDecoder

    type GobDecoder interface {
    GobEecode([]byte) error
    }

    GobDecoder是一个描述数据的结构,提供自己的方案来解码GobE内从der发送的数据
    2)GobEncoder

    type GobEncoder interface {
    GobEncode() ([]byte, error)
    }

    GobEncoder是一个描述数据的接口,提供自己的方案来将数据编码提供GobDecoder接受并编码。一个实现了GobEnoder接口和GobDecoder接口的类型可以完全控制自身数据的表示,因此可以包含非导出子段、通道、函数等数据,这些数据gob流正常使用不能传输的

    // A Decoder manages the receipt of type and data information read from the
    // remote side of a connection.
    type Decoder struct {
        mutex        sync.Mutex                              // each item must be received atomically
        r            io.Reader                               // source of the data
        buf          bytes.Buffer                            // buffer for more efficient i/o from r
        wireType     map[typeId]*wireType                    // map from remote ID to local description
        decoderCache map[reflect.Type]map[typeId]**decEngine // cache of compiled engines
        ignorerCache map[typeId]**decEngine                  // ditto for ignored objects
        freeList     *decoderState                           // list of free decoderStates; avoids reallocation
        countBuf     []byte                                  // used for decoding integers while parsing messages
        tmp          []byte                                  // temporary storage for i/o; saves reallocating
        err          error
    }
    
    
    // An Encoder manages the transmission of type and data information to the
    // other side of a connection.
    type Encoder struct {
        mutex      sync.Mutex              // each item must be sent atomically
        w          []io.Writer             // where to send the data
        sent       map[reflect.Type]typeId // which types we've already sent
        countState *encoderState           // stage for writing counts
        freeList   *encoderState           // list of free encoderStates; avoids reallocation
        byteBuf    bytes.Buffer            // buffer for top-level encoderState
        err        error
    }
    

    1)func Register(value interface{})

    Register记录value下层具体值得类型和其名称。该名称将用来识别发送或接收接口类型值下层的具体类型。本函数只应在初始化调用,如果类型和名字的映射不是一一对应的,会panic。

    2)func RegisterName(name string, value interface{})

    RegisterName,使用自定义的名称替代类型的默认名称。

    3)func NewDecoder(r io.Reader) *Decoder

    参数列表:r Reader对象
    返回值:*Decoder 指向Decoder的指针
    功能说明:这个函数主要是给r创建一个decoder实例

    4)func (des *Decoder) Decode(e interface{}) error

    参数列表:e 空接口类型,可以处理任何类型的数据
    返回值:error
    功能说明:此函数是Decoder的方法即(method),需要使用NewDcoder()创建*Decoder对象后,才可以使用

    5)func (dec *Decoder) DecodeValue(v refletc.Value) error

    6)func NewEncoder(w io.Writer) *Encoder

    7)func (enc *Encoder) Encode(e interface{}) error

    参数列表:v 序列化gob对象
    返回值:error错误
    功能说明:这个函数主要是讲encode编码的gob数据写入到相关联的对象

    8)func (enc *Encoder) EncodeValue(value reflect.Value) error

    demo1:自定义gob规则
    1)实现GobDecoder、GobEncoder这两个接口
    2)编写代码
    一篇讲解重新gob的博客,链接
    demo2:创建一个编码器,传输一些值,用解码器接收它们。
    示例:

    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() {
    	// 初始化编码器和解码器。 通常是enc和dec
    	// 绑定到网络连接和编码器和解码器会
    	// 在不同的进程中运行。
    	var network bytes.Buffer        // 替代网络连接
    	enc := gob.NewEncoder(&network) // 将写入网络。
    	dec := gob.NewDecoder(&network) // 将从网络上读取。
    	// Encoding(发送)一些值。
    	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)
    	}
    
    	// Decode(接收)并打印值。
    	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)
    
    }
    

    参考:https://cloud.tencent.com/developer/section/1141539
    https://developer.aliyun.com/article/676396

  • 相关阅读:
    LeetCode 24. Swap Nodes in Pairs (两两交换链表中的节点)
    LeetCode 1041. Robot Bounded In Circle (困于环中的机器人)
    LeetCode 1037. Valid Boomerang (有效的回旋镖)
    LeetCode 1108. Defanging an IP Address (IP 地址无效化)
    LeetCode 704. Binary Search (二分查找)
    LeetCode 744. Find Smallest Letter Greater Than Target (寻找比目标字母大的最小字母)
    LeetCode 852. Peak Index in a Mountain Array (山脉数组的峰顶索引)
    LeetCode 817. Linked List Components (链表组件)
    LeetCode 1019. Next Greater Node In Linked List (链表中的下一个更大节点)
    29. Divide Two Integers
  • 原文地址:https://www.cnblogs.com/whiteBear/p/15551015.html
Copyright © 2011-2022 走看看