18 Go的Gob

概述

在上一节的内容中,我们介绍了Go的文件操作,包括:读取文件、写入文件、删除文件、目录操作、遍历目录下文件等。在本节中,我们将介绍Go的Gob。Gob是Go语言中的一种序列化二进制格式,用于在Go语言之间进行数据传输和持久化存储,具有高效和紧凑的特点。Gob编码器将Go语言中的数据结构转换为二进制格式,而Gob解码器则将二进制格式的数据解码为Go语言中的数据结构。Gob使用可扩展的编码方案,可以处理任意类型的数据结构,包括:数组、切片、映射、嵌套结构等。

Gob简介

Gob是专门为Go语言设计,用于序列化和反序列化数据的一种格式,位于"encoding/gob"包中。

Gob的特点在于它是一种自描述的二进制格式,包含所有类型的描述,并且可以由Go语言解码,而无需了解文件的内容。只有可导出的字段会被编码,零值会被忽略。在解码结构体的时候,只有同时匹配名称和可兼容类型的字段才会被解码。当源数据类型增加新字段后,Gob解码仍然可以正常工作,解码客户端会继续识别以前存在的字段。

注意:Gob并不是一种不同于Go的语言,而是在编码和解码过程中用到了Go的反射。它是一种二进制格式,不像Json或XML那样是文本格式。

Gob编码

Gob编码器可以将Go语言中的数据结构转换为二进制格式,以便在网络传输或持久化存储时使用。下面是一些常用的编码函数。

NewEncoder(io.Writer) Encoder:创建一个新的编码器,用于将Go语言的数据结构编码为二进制格式。参数是一个io.Writer,编码的数据将写入该Writer中。

Encode(interface{}) error:使用指定的编码器将一个Go语言的数据结构编码为二进制格式,并写入指定的Writer中。参数是一个实现了interface{}类型的值,该函数将自动为该值编码。

GobEncode(interface{}) (\[\]byte, error):将一个Go语言的数据结构编码为Gob格式的字节切片,参数是一个实现了interface{}类型的值,该函数将自动为该值编码。

在下面的示例代码中,我们首先定义了一个Person结构体,它具有Name和Age两个字段。然后,我们创建了一个Person对象person。接下来,我们创建了一个文件person.gob,用于写入编码后的数据。最后,我们创建了一个编码器encoder,它将Person对象编码为Gob格式并写入文件。注意:Person结构体中的属性名必须为大写,否则编码时会出错,提示:"gob: type main.Person has no exported fields"。

Go 复制代码
package main

import "os"
import "fmt"
import "encoding/gob"

type Person struct {
    Name string
    Age  int
}

func main() {
    // 创建一个Person对象
    person := Person{"Mike", 18}

    // 创建文件,用于写入编码后的数据
    file, err := os.Create("person.gob")
    if err != nil {
        fmt.Println("Create failed:", err)
        return
    }

    defer file.Close()

    // 创建编码器,将Person对象编码为GOB格式并写入文件
    encoder := gob.NewEncoder(file)
    err = encoder.Encode(person)
    if err != nil {
        fmt.Println("Encode failed:", err)
        return
    }

    fmt.Println("Encode success")
}

Gob解码

Gob解码器可以将二进制格式的数据解码为Go语言中的数据结构,下面是一些常用的解码函数。

NewDecoder(io.Reader) Decoder:创建一个新的解码器,用于从二进制格式的数据中解码出Go语言的数据结构。参数是一个io.Reader,解码的数据将从该Reader中读取。

Decode(interface{}) error:使用指定的解码器从二进制格式的数据中解码出一个Go语言的数据结构,并存储在指定的值中。参数是一个实现了interface{}类型的值,该函数将自动为该值解码。

GobDecode(\[\]byte, interface{}) error:从一个Gob格式的字节切片中解码出一个Go语言的数据结构,并存储在指定的值中。参数是一个实现了interface{}类型的值,该函数将自动为该值解码。

在下面的示例代码中,我们首先定义了一个Person结构体,它具有Name和Age两个字段。接下来,我们读取了上述编码好的文件person.gob,用于从文件中解码数据。最后,我们创建了一个解码器decoder,用于从文件中读取Gob格式的数据,并解码存入到person对象中。

Go 复制代码
package main

import "os"
import "fmt"
import "encoding/gob"

type Person struct {
    Name string
    Age  int
}

func main() {
    person := Person{}

     // 创建一个文件用于写入编码后的数据
     file, err := os.Open("person.gob")
     if err != nil {
         fmt.Println("Open failed:", err)
         return
     }

     defer file.Close()

     // 创建解码器,从文件中解码GOB格式数据并存入Person对象
     decoder := gob.NewDecoder(file)
     err = decoder.Decode(&person)
     if err != nil {
         fmt.Println("Decode failed:", err)
         return
     }

     // 输出:Decode success: {Mike 18}
     fmt.Println("Decode success:", person)
}

除了可以将数据结构编码到文件中,还可以将数据结构编码到字节切片中,并从字节切片中解码。

在下面的示例代码中,我们首先定义了一个Person结构体。然后,我们创建了一个缓冲区buf,用于存储编码后的数据。接下来,我们创建了一个编码器encoder,它将数据person编码为gob格式并写入缓冲区buf。最后,我们创建了一个解码器decoder,它从缓冲区中读取编码后的数据并解码为Person对象decodedPerson。

Go 复制代码
package main

import "fmt"
import "bytes"
import "encoding/gob"

type Person struct {
    Name string
    Age  int
}
  
func main() {
    // 创建一个缓冲区,用于编码数据
    var buf bytes.Buffer
    // 创建一个编码器,将数据编码为gob格式并写入缓冲区
    encoder := gob.NewEncoder(&buf)
    // 创建一个Person对象
    person := Person{"Mike", 18}

    // 将Person对象编码为gob格式并写入缓冲区
    err := encoder.Encode(person)
    if err != nil {
        fmt.Println("Encode failed:", err)
        return
    }

    // 从缓冲区中读取编码后的数据
    decodedPerson := Person{}
    decoder := gob.NewDecoder(&buf)
    err = decoder.Decode(&decodedPerson)
    if err != nil {
        fmt.Println("Decode failed:", err)
        return
    }

    // 输出:Decoded data: {Mike 18}
    fmt.Println("Decoded data:", decodedPerson)
}
相关推荐
福大大架构师每日一题1 天前
ollama v0.30.7 正式发布:Hermes 桌面端落地,接口、文档、底层依赖全方位优化
golang·log4j
不爱编程的小陈1 天前
深入解析 Go 网络 I/O 的底层引擎:从 epoll 到 netpoll
服务器·网络·golang
何以解忧,唯有..1 天前
Go 语言数据类型详解:从基础到复合类型
开发语言·golang·mfc
踏着七彩祥云的小丑1 天前
Go学习第7天:Map集合 + 递归函数 + 类型转换
开发语言·学习·golang·go
何以解忧,唯有..1 天前
Go语言变量的声明方式详解
开发语言·后端·golang
寂夜了无痕1 天前
Go 多版本管理工具G 保姆级安装配置教程
golang·go多版本管理
张忠琳1 天前
【Go 1.26.4】Golang Slice 深度解析
开发语言·后端·golang
张忠琳2 天前
【Go 1.26.4】Golang Channel 深度解析
开发语言·后端·golang
张忠琳2 天前
【Go 1.26.4】Golang Map 深度解析
开发语言·后端·golang
何以解忧,唯有..2 天前
Go 语言安装与环境配置完整指南
开发语言·后端·golang