gob preserves interface?

269 views
Skip to first unread message

Awaken

unread,
May 22, 2012, 12:37:00 AM5/22/12
to golan...@googlegroups.com
Hi all,
For the attached code, I got the following error:
gob: cannot assign value of type main.B to main.P
I also test the behavior of gob.
It seems that gob will lose the pointer (to b in this case) if the container is an interface (c.J in this case).
Any idea of how to circumvent this? I really need J to store a pointer to a struct rather than a copy of the struct.

package main

import (
"bytes"
"encoding/gob"
"fmt"
)

type P interface {
Q()
}

type A struct {
J P
}

type B struct {
P int
}

func (b *B) Q() {
}

func main() {
b := B{2}
c := A{&b}
gob.Register(A{})
gob.Register(B{})
var buffer bytes.Buffer
en := gob.NewEncoder(&buffer)
if err := en.Encode(&c); err != nil {
panic(err.Error())
}
buff := bytes.NewBuffer(buffer.Bytes())
de := gob.NewDecoder(buff)
if err := de.Decode(&c); err != nil {
fmt.Println(err.Error())
} else {
fmt.Println(c)
}
}

Rob 'Commander' Pike

unread,
May 22, 2012, 2:55:15 AM5/22/12
to Awaken, golan...@googlegroups.com
There is no such thing as a pointer in gobs. All data items are
flattened. Thus, when the B is transmitted it is sent as a value, not
as a pointer. The gob decoder for interfaces should perhaps attempt an
auto indirection of the value before giving up. It's an easy fix.

Please file an issue. In the meantime you could always box your struct
or fields and write a custom GobEncoder/GobDecoder.

-rob

Awaken

unread,
May 22, 2012, 8:04:47 AM5/22/12
to golan...@googlegroups.com, Awaken
Thanks Rob.
I think someone encounters a similar issue. And it seems that it has already been fixed long time ago.
But I cannot find the issue in the issue tracking.
You can find information in this post:

m...@xoba.com

unread,
Jun 2, 2013, 5:10:37 PM6/2/13
to golan...@googlegroups.com, Awaken
this issue still seems active? --- i just ran into this bug in my own code. for the example already given in this discussion, i've narrowed the problem down to the presence or absence of B's pointer receiver, which theoretically shouldn't have anything to do with data structures and encodings per se?

so, this works:

func (b B) Q() {
}

but this doesn't:

func (b *B) Q() {
}

only difference is "*" character for pointer receiver.

i'm using latest working build: go version devel +a115231d557b Sun Jun 02 09:13:12 2013 +1000 linux/amd64

Rob Pike

unread,
Jun 3, 2013, 9:47:26 AM6/3/13
to m...@xoba.com, golan...@googlegroups.com, Awaken
You don't explain your problem but I suspect it's related to the
original issue, which was programmer error. See the resolution of
https://code.google.com/p/go/issues/detail?id=3658 .

-rob

m...@xoba.com

unread,
Jun 3, 2013, 10:11:04 AM6/3/13
to golan...@googlegroups.com, m...@xoba.com, Awaken
many thanks rob!
Reply all
Reply to author
Forward
0 new messages