Gob Decoder Return EOF Error

Я пытаюсь реализовать основанную на интерфейсе очередь сообщений, где задания передаются в виде байтов в очередь повторного выполнения. Но я продолжаю получать ошибку EOF при попытке декодировать поток байтов.

https://play.golang.org/p/l9TBvcn9qg

Может ли кто-нибудь указать мне правильное направление?

Спасибо!

3 ответа

В вашем примере 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"}}
   // ...
}

Нашел ответ на проблему у Марка выше. Я забыл сделать gob.Register(B{})

https://play.golang.org/p/7rQDHvMhD7

Я получил эту ошибку при попытке загрузить файлы gob, которые не были успешно сохранены(), но мне не хватало достаточной обработки ошибок при сохранении(), чтобы это узнать.

Моя функция сохранения теперь немного безумна, но мне она нравится:

      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{}{})
}
Другие вопросы по тегам