gob encoded empty slices decoding as nil

551 views
Skip to first unread message

mi...@hrmweb.com.au

unread,
May 17, 2015, 7:51:40 PM5/17/15
to golan...@googlegroups.com
Hi all, as per the subject I'm seeing empty slices being decoded as nil when using gob.  I'm very surprised I haven't come across it before as I've been using gob fairly extensively in a project.

An example illustrating what's happening: https://play.golang.org/p/UdxICjqPnM

I understand that zero value properties aren't transmitted (https://golang.org/pkg/encoding/gob/#pkg-overview), but I can see the property in the encoded data and as I understand it an empty slice isn't the zero value for a slice.

Wondering if someone could provide some insight, I'm hoping I don't need to check all the properties and reinitialise empty slices as part of my decode logic.

Cheers,
Michael

Roberto Zanotto

unread,
May 17, 2015, 8:45:33 PM5/17/15
to golan...@googlegroups.com, mi...@hrmweb.com.au
I never understood why a zero value slice is not the same thing as a nil slice, if you inspect them with unsafe you find that one of the two is not really zero (doesn't make sense to me)... anyway they behave pretty much the same and can be used interchangeably in most situations (someone correct me if I'm wrong): both have 0 len and cap, you can append to the nil slice without problems, you can range on both https://play.golang.org/p/QQWdsWbEXB
So there should be no need to initialize nil slices and probably that's the reason why you never encountered the problem before.
Still doesn't explain the apparent incongruity you found with gob.

Matt Harden

unread,
May 17, 2015, 9:03:09 PM5/17/15
to Roberto Zanotto, golan...@googlegroups.com, mi...@hrmweb.com.au
The zero value of a slice type is in fact nil. I think what Roberto means is that an empty (and zero capacity) slice is not the same as a nil. I don't have an answer as to why, except to say that I personally would not expect for a given initialized slice s, s[0:0:0] == nil to be true. I would be surprised if it were.

For Michael, I agree that gob isn't being all that consistent here, but why is it that you feel you would have to reinitialize empty slices after decoding them? As Roberto pointed out they behave the same in practice, except if you compare with nil.

Hopefully gob does not decode an empty map as nil; that would be a totally different situation since a nil map behaves very differently from an empty one.


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Message has been deleted

Roberto Zanotto

unread,
May 17, 2015, 10:16:08 PM5/17/15
to golan...@googlegroups.com, mi...@hrmweb.com.au, roby...@gmail.com
I was actually thinking that an uninitialized slice was not a nil slice :( I guess I just added confusion to the discussion, forgive me :)

Kevin Malachowski

unread,
May 18, 2015, 10:54:25 AM5/18/15
to golan...@googlegroups.com
Since empty slices are different than nil slices you can use them in your API. Once I used the pattern of returning 'nil' to represent EOF and an empty slice to represent 'the pipe isn't closed by no data was sent recently'.

Roberto Zanotto

unread,
May 18, 2015, 8:44:09 PM5/18/15
to golan...@googlegroups.com, mi...@hrmweb.com.au
Still it looks like a bug. I filed an issue, hoping that we didn't miss anything...

Roberto Zanotto

unread,
May 18, 2015, 9:18:14 PM5/18/15
to golan...@googlegroups.com, mi...@hrmweb.com.au
Looks like we were missing something after all -_-
When decoding the slice with dec.Decode(&dest) it just appends the encoded elements (ints) to dest, and since there are no ints to append, the destination slice stays nil. So gob is not able to distinguish between empty and nil slices by design. If you don't want nil slices when decoding, you should do it like this https://play.golang.org/p/l5KySo1n7o

Caleb Spare

unread,
May 18, 2015, 9:24:44 PM5/18/15
to Roberto Zanotto, golang-nuts, mi...@hrmweb.com.au
​In my experience, most code shouldn't care about the difference between nil and empty, non-nil slices.

On Mon, May 18, 2015 at 6:18 PM, Roberto Zanotto <roby...@gmail.com> wrote:
Looks like we were missing something after all -_-
When decoding the slice with dec.Decode(&dest) it just appends the encoded elements (ints) to dest, and since there are no ints to append, the destination slice stays nil. So gob is not able to distinguish between empty and nil slices by design. If you don't want nil slices when decoding, you should do it like this https://play.golang.org/p/l5KySo1n7o

--

Roberto Zanotto

unread,
May 18, 2015, 9:29:05 PM5/18/15
to golan...@googlegroups.com, mi...@hrmweb.com.au, roby...@gmail.com
I totally agree. It's just a matter of principle here :)

roger peppe

unread,
May 21, 2015, 3:42:22 AM5/21/15
to mi...@hrmweb.com.au, golang-nuts
The gob encoding doesn't have any concept of nil.
For example, you cannot encode a slice or a map
containing nil elements: http://play.golang.org/p/PRjsF-_gar
Reply all
Reply to author
Forward
0 new messages