8

我已阅读 (gob) 的文档,但遇到了一些问题:

现在我知道如何编码结构和解码:

func main() {
    s1 := &S{
        Field1: "Hello Gob",
        Field2: 999,
    }
    log.Println("Original value:", s1)
    buf := new(bytes.Buffer)
    err := gob.NewEncoder(buf).Encode(s1)
    if err != nil {
        log.Println("Encode:", err)
        return
    }

    s2 := &S{}
    err = gob.NewDecoder(buf).Decode(s2)
    if err != nil {
        log.Println("Decode:", err)
        return
    }
    log.Println("Decoded value:", s2)
}

但是我不知道这种方法的目的,gob.Register()有人可以向我解释什么时候使用它,为什么?

4

3 回答 3

11

如果您只处理具体类型(结构),那么您实际上并不需要它。一旦你处理了接口,你必须首先注册你的具体类型。

例如,假设我们有这些结构和接口(结构实现了接口):

type Getter interface {
    Get() string
}


type Foo struct {
    Bar string
}

func (f Foo)Get() string {
    return f.Bar
}

要将Fooover gob 作为 a发送Getter并解码回来,我们必须首先调用

gob.Register(Foo{})

所以流程是:

// init and register
buf := bytes.NewBuffer(nil)
gob.Register(Foo{})    


// create a getter of Foo
g := Getter(Foo{"wazzup"})

// encode
enc := gob.NewEncoder(buf)
enc.Encode(&g)

// decode
dec := gob.NewDecoder(buf)
var gg Getter
if err := dec.Decode(&gg); err != nil {
    panic(err)
}

现在尝试删除Register,这将不起作用,因为 gob 不知道如何将事物映射回其适当的类型。

于 2015-09-20T09:00:34.500 回答
0

正如http://golang.org/pkg/encoding/gob/#Register所说:

只有将作为接口值的实现传输的类型才需要注册。

所以你的演示不需要它。

于 2015-09-20T08:56:14.607 回答
0

如果要对map[string]interface{}进行编码/解码,由于map的字段是作为接口类型括起来的,那么我们需要先注册具体的类型。


package main

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

type SomeStruct struct {
    Text string
}

func main() {
    var bytes bytes.Buffer

    // Remove one of these, then the decoding will produce error
    gob.Register(SomeStruct{})
    gob.Register([]interface{}{})
    gob.Register([]SomeStruct{})
    gob.Register(map[string]SomeStruct{})

    writer := gob.NewEncoder(&bytes)

    err := writer.Encode(map[string]interface{}{
        "SomeStruct": SomeStruct{"Halo"},
        "SomeSlice":  []interface{}{},
        "SomeSliceStruct": []SomeStruct{
            {
                Text: "SomeText",
            },
        },
        "SomeMapStruct": map[string]SomeStruct{
            "S": {"Test"},
        },
    })
    if err != nil {
        log.Fatalf("Error on encode process: %v\n", err)
        return
    }

    reader := gob.NewDecoder(&bytes)
    var aMap map[string]interface{}
    err = reader.Decode(&aMap)
    if err != nil {
        log.Fatalf("Error on decode process: %v\n", err)
        return
    }

    fmt.Printf("Decode is successful: %+v\n", aMap)
}

于 2020-05-18T06:06:54.937 回答