The error gob: duplicate type received

2,233 views
Skip to first unread message

hash code

unread,
Jun 7, 2012, 10:26:50 AM6/7/12
to golan...@googlegroups.com
I have a structure

type ListData struct {
Value []interface{}
}

and

type SomeStuct1 struct {
Id           int
Title         string
}

type SomeStuct2 struct {
Id            int
Name        string
}

I've registered it

func init() {
gob.Register(ListData{})
gob.Register(SomeStuct1{})
gob.Register(SomeStuct2{})
}

I use it like this

func makeInterfaceData(s1 []SomeStuct1) []interface{} {
length := len(s1)
returnValues := make([]interface{}, length)
for i, _ := range s1 {
returnValues[i] = s1[i]
}
return returnValues
}

When I try to convert the bytes into the structure, I get an error - gob: duplicate type received. Doing the same operations with s2 there is no error.

func makeListDataFromByte(value []byte) []interface{} {
var data ListData
b := bytes.NewBuffer(value)
d := gob.NewDecoder(b)
if err := d.Decode(&data); err != nil {
HandleError(err)
return nil
}
return data.Value
}

hash code

unread,
Jun 9, 2012, 11:04:52 AM6/9/12
to golan...@googlegroups.com
I found that this happens if the structure has a field of type pointer to time.Time (exactly pointer). How to register a type time.Time, so that no error occurred?

hash code

unread,
Jun 9, 2012, 11:10:28 AM6/9/12
to golan...@googlegroups.com
The error will if I have the following architecture.

type S1 struct {
    Time * time.Time
}

type S2 struct {
    S S1
}

Here S1 is decoded correctly. The error occurs when decoding S2.

Rob 'Commander' Pike

unread,
Jun 9, 2012, 11:10:49 AM6/9/12
to hash code, golan...@googlegroups.com
It's extremely unlikely that you actually need a pointer to a
time.Time and much likelier that you should use the time.Time value in
your structure instead. That's how it's intended to be used. It's a
small value.

As far as registering *time.Time is concerned, although it's not the
right fix, you register a *time.Time (fancy that). Simplest form is
gob.Register((*time.Time)(nil)).

-rob

Rob 'Commander' Pike

unread,
Jun 9, 2012, 11:12:00 AM6/9/12
to hash code, golan...@googlegroups.com
Please create a complete, self-contained example showing the problem
and provided it here or, better, file an issue.

Thanks.

-rob

hash code

unread,
Jun 9, 2012, 11:16:47 AM6/9/12
to golan...@googlegroups.com
If S1 will be included in S2 as the interface, the error will not be.

For example

type IS interface {
    Foo()
}

type S1 struct {
    Time * time.Time
}

func (s *S1) Foo() {
}

type S2 struct {
    S IS
}

In this case, the error will not be.

hash code

unread,
Jun 9, 2012, 11:24:18 AM6/9/12
to golan...@googlegroups.com, hash code
gob.Register((*time.Time)(nil)) - is not working. I use a pointer to time.Time because it is necessary to verify the user enters a value or not (compared to nil). How to perform a similar comparison, without using a pointer?

суббота, 9 июня 2012 г., 19:10:49 UTC+4 пользователь Rob 'Commander' Pike написал:

Rob 'Commander' Pike

unread,
Jun 9, 2012, 11:34:30 AM6/9/12
to hash code, golan...@googlegroups.com
Use time.IsZero.

-rob

Rob 'Commander' Pike

unread,
Jun 9, 2012, 11:37:05 AM6/9/12
to hash code, golan...@googlegroups.com
As I said before, please create a complete, self-contained example
showing the problem
and provided it here or, better, file an issue.

-rob

Mark B.

unread,
Feb 7, 2015, 2:29:38 PM2/7/15
to golan...@googlegroups.com, hashc...@gmail.com
On Saturday, June 9, 2012 at 11:37:05 AM UTC-4, Rob 'Commander' Pike wrote:

As I said before, please create a complete, self-contained example 
showing the problem 
and provided it here or, better, file an issue. 


https://play.golang.org/p/_-S8JFWo-a

Output:

write &{Id:0 Msg:a}  	of type *main.HeardIt
write &{Id:1 Msg:dup}  	of type *main.HeardIt
read  &{Id:0 Msg:a}  	of type *main.HeardIt
read  &{Id:0 Msg:a}  	of type *main.HeardIt, got gob: duplicate type received

Looks like second call to encode re-writes type info, since file is opened in append mode.

Do I need to rewrite entire gob file each time?

Thanks,

Mark

Egon

unread,
Feb 7, 2015, 4:05:16 PM2/7/15
to golan...@googlegroups.com, hashc...@gmail.com
The usage of encoder and decoder should be "symmetric" - for every encoder you should create similar amount of decoders. (https://play.golang.org/p/HZJGicxgSL)
See the documentation how it writes the gob stream...

+ Egon

Egon

unread,
Feb 7, 2015, 4:08:06 PM2/7/15
to golan...@googlegroups.com, hashc...@gmail.com


On Saturday, 7 February 2015 23:05:16 UTC+2, Egon wrote:
The usage of encoder and decoder should be "symmetric" - for every encoder you should create similar amount of decoders. (https://play.golang.org/p/HZJGicxgSL)
See the documentation how it writes the gob stream...

Probably https://play.golang.org/p/SCOGpko1Ac is better because it creates a smaller stream.
(You want to reuse the same encoder as long as possible.)

Mark B.

unread,
Feb 7, 2015, 6:19:50 PM2/7/15
to golan...@googlegroups.com, hashc...@gmail.com
On Saturday, February 7, 2015 at 4:08:06 PM UTC-5, Egon wrote:

On Saturday, 7 February 2015 23:05:16 UTC+2, Egon wrote:
The usage of encoder and decoder should be "symmetric" - for every encoder you should create similar amount of decoders. (https://play.golang.org/p/HZJGicxgSL)
See the documentation how it writes the gob stream...


Ok, I think I understand:

When gob writing to a file, 
to intermittently append new objects
without re-writing the type header data
on each append
I need to use the same encoder instance.

That means I need to keep the file handle open
(since creating the encoder
requires the stream).

My other choice is to not append 
and simply rewrite the entire file.

(I re-read the docs carefully,
but did not see the text you refer to.)

I wonder why the decoder thinks it's an error
if the same type declaration appears twice.
The library could assume
that I know what I'm doing,
and let the first (or last) type definition win,
and panic if that is not the case.
(Maybe that panic part is hard?)

Thanks,

Mark
Reply all
Reply to author
Forward
0 new messages