48.Go gob

Gob是Go特定的序列化方法,主要为RPC(远程过程调用)创建。

它支持除通道和函数之外的所有Go数据类型。

Gob将类型信息写入序列化数据中。

它是一种二进制格式,因此比JSON或XML更有效。

包含类型信息使编码和解码对编码器和解码器之间的差异具有鲁棒性。

将数据编码到文件并从文件解码

type User struct {
    Username string
    Password string
}

func writeToGob(path string, user *User) error {
    file, err := os.Create(path)
    if err != nil {
        return err
    }

    encoder := gob.NewEncoder(file)

    err = encoder.Encode(user)
    if err != nil {
        file.Close()
        return err
    }

    return file.Close()
}

func write(path string, user *User) {
    err := writeToGob(path, user)
    if err != nil {
        log.Fatalf("writeToGob() failed with '%s'\n", err)
    }
    st, err := os.Stat(path)
    if err != nil {
        log.Fatalf("os.Stat() failed with '%s'\n", err)
    }
    fmt.Printf("Wrote user struct to file '%s' of size %d.\n", path, st.Size())
}

func read(path string) {
    user := User{}
    file, err := os.Open(path)
    if err != nil {
        log.Fatalf("os.Open('%s') failed with '%s'\n", path, err)
    }
    defer file.Close()

    decoder := gob.NewDecoder(file)
    err = decoder.Decode(&user)
    if err != nil {
        log.Fatalf("decoder.Decode() failed with '%s'\n", err)
    }
    fmt.Printf("\nRead from '%s' user:\n%#v\n", path, user)    
}

func main() {
     user := User{
        Username: "Angus",
        Password: "1234",
    }
    path := "user.gob"
    write(path, &user)
    read(path)
}

Wrote user struct to file 'user.gob' of size 62.

Read from 'user.gob' user:
main.User{Username:"Angus", Password:"1234"}

编码接口

package main

import (
    "encoding/gob"
    "fmt"
    "os"
)

type User struct {
    Username string
    Password string
}

type Admin struct {
    Username string
    Password string
    IsAdmin  bool
}

type Deleter interface {
    Delete()
}

func (u User) Delete() {
    fmt.Println("User ==> Delete()")
}

func (a Admin) Delete() {
    fmt.Println("Admin ==> Delete()")
}

func main() {

    user := User{
        "zola",
        "supersecretpassword",
    }

    admin := Admin{
        "john",
        "supersecretpassword",
        true,
    }

    file, _ := os.Create("user.gob")

    adminFile, _ := os.Create("admin.gob")

    defer file.Close()

    defer adminFile.Close()

    gob.Register(User{}) // registering the type allows us to encode it

    gob.Register(Admin{}) // registering the type allows us to encode it

    encoder := gob.NewEncoder(file)

    adminEncoder := gob.NewEncoder(adminFile)

    InterfaceEncode(encoder, user)

    InterfaceEncode(adminEncoder, admin)

}

func InterfaceEncode(encoder *gob.Encoder, d Deleter) {

    if err := encoder.Encode(&d); err != nil {
        fmt.Println(err)
    }
}

解码接口

package main

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

type User struct {
    Username string
    Password string
}

type Admin struct {
    Username string
    Password string
    IsAdmin  bool
}

type Deleter interface {
    Delete()
}

func (u User) Delete() {
    fmt.Println("User ==> Delete()")
}

func (a Admin) Delete() {
    fmt.Println("Admin ==> Delete()")
}

func main() {

    file, _ := os.Open("user.gob")

    adminFile, _ := os.Open("admin.gob")

    defer file.Close()

    defer adminFile.Close()

    gob.Register(User{}) // registering the type allows us to encode it

    gob.Register(Admin{}) // registering the type allows us to encode it

    var admin Deleter

    var user Deleter

    userDecoder := gob.NewDecoder(file)

    adminDecoder := gob.NewDecoder(adminFile)

    user = InterfaceDecode(userDecoder)

    admin = InterfaceDecode(adminDecoder)

    fmt.Println(user)

    fmt.Println(admin)

}

func InterfaceDecode(decoder *gob.Decoder) Deleter {

    var d Deleter

    if err := decoder.Decode(&d); err != nil {
        log.Fatal(err)
    }

    return d
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Go语言标准库 archive[https://www.apiref.com/go-zh/package.htm#...
    ixiaoyang8阅读 4,654评论 0 0
  • 一、常用包 二、完整包列表
    随风化作雨阅读 4,338评论 0 0
  • 为了让数据结构能够在网络中传输或保存到文件,它必须被编码后再解码。目前有多种可用的编码方式,比如JSON、XML、...
    JunChow520阅读 5,031评论 1 1
  • 目录 1.go 各种代码运行 2.go 在线编辑代码运行 3.通过 Gob 包序列化二进制数据 4.使用 ...
    杨言锡阅读 4,813评论 0 1
  • 客户端与服务之间通过数据交换来通信。因为数据可能是高度结构化的,所以在传输前必须进行序列化。这一章将研究序列化基础...
    GeminiGirl0604阅读 4,496评论 0 1