DEV Community

林子篆
林子篆

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

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)