Gob解码器返回EOF错误

1aaf6o9v  于 2023-03-16  发布在  Go
关注(0)|答案(3)|浏览(147)

我正在尝试实现一个基于接口的消息队列,其中作业作为字节被推送到一个redis队列。但是当我尝试解码字节流时,我一直收到一个EOF错误。
https://play.golang.org/p/l9TBvcn9qg
有人能给我指一下正确的方向吗?
谢谢大家!

sr4lhrrt

sr4lhrrt1#

在Go Playground的例子中,你试图对一个接口进行编码,但是接口没有具体的实现,如果你从A结构体中删除了接口,就应该可以了。

package main

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

type testInterface interface{}

type A struct {
  Name string
  Interface *B // note this change here
}

type B struct {
  Value string
}

func main() {
  var err error
  test := &A {
    Name: "wut",
    Interface: &B{Value: "BVALUE"},
  }
  buf := bytes.NewBuffer([]byte{})
  enc := gob.NewEncoder(buf)
  dec := gob.NewDecoder(buf)

  // added error checking as per Mark's comment
  err = enc.Encode(test)
  if err != nil {
    panic(err.Error())
  }

  result := &A{}
  err := dec.Decode(result)
  fmt.Printf("%+v\n", result)
  fmt.Println("Error is:", err)
  fmt.Println("Hello, playground")
}

此外,作为旁注,您将看到类似以下的某种输出:&{Name:wut Interface:0x1040a5a0},因为A正在引用对B结构的引用。要进一步清除该引用:

type A struct{
  Name string
  Interface B // no longer a pointer
}

func main() {
   // ...
   test := &A{Name: "wut", Interface: B{Value: "BVALUE"}}
   // ...
}
u7up0aaq

u7up0aaq2#

从上面的马克那里找到了问题的答案。我忘记做一个gob.Register(B{})
https://play.golang.org/p/7rQDHvMhD7

von4xj4u

von4xj4u3#

我在尝试加载gob文件时遇到了这个错误,但save()没有成功,但我在save()上缺乏足够的错误处理来了解它。
我的保存功能现在有点疯狂,但我喜欢它:

func SaveToDisk[T any](filepath string, data T) {
    f, err := os.Create(filepath)
    if err != nil {
        log.Fatal(errors.Wrap(err, "os.Create()"))
    }
    defer func() {
        err := f.Close()
        if err != nil {
            log.Fatal(errors.Wrap(err, "f.Close()"))
        }
    }()

    writer := bufio.NewWriter(f)
    dataEncoder := gob.NewEncoder(writer)
    err = dataEncoder.Encode(data)
    if err != nil {
        log.Fatal(errors.Wrap(err, "dataEncoder.Encode()"))
    }
    err = writer.Flush() // Flush the data to the file
    if err != nil {
        log.Fatal(errors.Wrap(err, "writer.Flush()"))
    }
}

原来我在保存()过程中遗漏了错误dataEncoder.Encode(): gob: type not registered for interface: map[string]interface {}
gob似乎无法在没有任何帮助的情况下封送接口,但您可以使用它注册接口类型来解决这个问题。为了解决这个问题,我所要做的就是:

func init() {
    gob.Register(map[string]interface{}{})
}

相关问题