I am new to gob and am having confusion on gob register. In my code, I have something like
var foo1 somestruct
var foo2 &somestruct
var foo3 anotherstruct
func call(a interface, b interface) {
var buf bytes.Buffer
argsEncoder := gob.NewEncoder(&buf)
gob.register(a)
gob.register(b)
err := argsEncoder.EncodeValue(reflect.ValueOf(&a))
}
And then I have two call of the method: call(foo1,foo3)
and call(foo2, foo3)
. I found that if they run separately, the function works fine. However, if you run them consecutively, it gives gob: registering duplicate names
. Is there a way to bypass this problem?
I also found that if I register only once for somestruct
, the next call call(foo2, foo3)
will also go on well. But when I check with reflect.TypeOf(a)
, they both gives me the type that was registered (somestruct, not somestruct and *somestruct).
encoding/gob
maintains a single, global type registry, not a per-encoder one. You can't (shouldn't) register types in yourcall()
function. You should do it once, e.g. in yourmain()
function.Like this:
Also note that
encoding/gob
does not transmit pointer values. Quoting from the package doc:So you don't have to register pointer and non-pointer types. The decoder will properly decode registered types, and generate pointers to them if the value they are decoded into are pointers to the known types.
Also you should not use pointers to interfaces, ever. The very rare cases when they needed, you'll know when you get there.
That said,
&a
is a pointer to interface because type ofa
isinterface{}
. This isn't needed, because interface values may wrap pointers.You also shouldn't encode
reflect.Value
values. Encodea
itself.