DEV Community

林子篆
林子篆

Posted on • Originally published at dannypsnl.github.io on

3

Weird behavior in Go: encoding/gob

Consider the following program:

type AState uint8

const (
    S1 AState = iota
    S2
    S3
)
Enter fullscreen mode Exit fullscreen mode

This is quite usual in Go. But we want to make it more expressive. So we have:

func (s *AState) ToS1() { *s = S1 }
func (s *AState) ToS2() { *s = S2 }
func (s *AState) ToS3() { *s = S3 }
Enter fullscreen mode Exit fullscreen mode

p.s. Replace ToS1 and others functions with meaningful names since it’s a real case in the product, I don’t want to show them directly.

Now consider a structure:

type Foo struct {
    AState *AState
}
Enter fullscreen mode Exit fullscreen mode

With decoding:

    foo := NewFoo()
    var buf bytes.Buffer
    enc := gob.NewEncoder(&buf)
    _ = enc.Encode(foo)
    unmarshalFoo := &Foo{}
    decBuf := bytes.NewBuffer(buf.Bytes())
    dec := gob.NewDecoder(decBuf)
    dec.Decode(unmarshalFoo)
Enter fullscreen mode Exit fullscreen mode

Guess what, the field AState has nil value. This is out of expected. A least, I thought it should be a pointer to S1 as what "encoding/json" does.

We have two ways to solve this.

First, remove the pointer from the field type.

type Foo struct {
    AState AState
}
Enter fullscreen mode Exit fullscreen mode

Or we can use iota + 1

const (
    S1 AState = iota + 1
        // ...
)
Enter fullscreen mode Exit fullscreen mode

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay