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: { }
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}}