I'm trying to de- and encode a struct which contains a Interface{} as field.
The problem there is, that the encoding works fine, but if I try to decode the data to data
the value gets { <nil>}
.
It actually works, if I change Data interface{}
to Data substring
, but this is not a solution for me because I want to cache the results of a query to a database which have different types depending on the query. (e.g. Users
or Cookies
)
http://play.golang.org/p/aX7MIfqrWl
package main
import (
"bytes"
"encoding/gob"
"fmt"
)
type Data struct {
Name string
Data interface{}
}
type SubType struct {
Foo string
}
func main() {
// Encode
encodeData := Data{
Name: "FooBar",
Data: SubType{Foo: "Test"},
}
mCache := new(bytes.Buffer)
encCache := gob.NewEncoder(mCache)
encCache.Encode(encodeData)
fmt.Printf("Encoded: ")
fmt.Println(mCache.Bytes())
// Decode
var data Data
pCache := bytes.NewBuffer(mCache.Bytes())
decCache := gob.NewDecoder(pCache)
decCache.Decode(&data)
fmt.Printf("Decoded: ")
fmt.Println(data)
}
Encoded: [37 255 129 3 1 1 4 68 97 116 97 1 255 130 0 1 2 1 4 78 97 109 101 1 12 0 1 4 68 97 116 97 1 255 132 0 0 0 29 255 131 3 1 1 7 83 117 98 84 121 112 101 1 255 132 0 1 1 1 3 70 111 111 1 12 0 0 0 19 255 130 1 6 70 111 111 66 97 114 1 1 4 84 101 115 116 0 0]
Decoded: {FooBar {Test}}
Encoded: [37 255 129 3 1 1 4 68 97 116 97 1 255 130 0 1 2 1 4 78 97 109 101 1 12 0 1 4 68 97 116 97 1 255 132 0 0 0 29 255 131 3 1 1 7 83 117 98 84 121 112 101 1 255 132 0 1 1 1 3 70 111 111 1 12 0 0 0 19 255 130 1 6 70 111 111 66 97 114 1 1 4 84 101 115 116 0 0]
Decoded: { }
Gob is a serialisation technique specific to Go. It is designed to encode Go data types specifically and does not at present have support for or by any other programming language. Gob packet is used to manage gob stream. It can send binary data stream between encoder (transmitter) and decoder (receiver).
To use gobs, create an Encoder and present it with a series of data items as values or addresses that can be dereferenced to values. The Encoder makes sure all type information is sent before it is needed. At the receive side, a Decoder retrieves values from the encoded stream and unpacks them into local variables.
The problem is that in your code, there is an error when executing encCache.Encode(encodeData)
but since you don't check for error, you don't realize that. The output is blank because encodedData fails to get encoded properly.
If you add error checking,
err := enc.Encode(encodeData)
if err != nil {
log.Fatal("encode error:", err)
}
Then you'd see something like
2013/03/09 17:57:23 encode error:gob: type not registered for interface: main.SubType
If you add one line to your original code before enc.Encode(encodeData),
gob.Register(SubType{})
Then you get expected output.
Decoded: {FooBar {Test}}
See http://play.golang.org/p/xt4zNyPZ2W
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With