I'm using go's encoding/gob to decode two different objects which type are T into a same object, but the object's bool member has not been changed after the second decode. Why?
package main
import (
"fmt"
"encoding/gob"
"bytes"
)
type T struct {
X int
Y string
Z bool
}
func main() {
t := T{}
buf := new(bytes.Buffer)
enc := gob.NewEncoder(buf)
dec := gob.NewDecoder(buf)
t1 := T{1, "1", true}
enc.Encode(t1)
dec.Decode(&t)
fmt.Printf("%+v
", t)
// If t is a new entity, the second decode into t can product expected result: {X:2 Y:2 Z:false}
// otherwise, t's bool member has not been changed after the second decode.
// t = T{}
t2 := T{2, "2", false}
enc.Encode(t2)
dec.Decode(&t)
fmt.Printf("%+v
", t)
// result:
// {X:1 Y:1 Z:true}
// {X:2 Y:2 Z:true}
}
Base on the document: https://golang.org/pkg/encoding/gob/#hdr-Encoding_Details
If a field has the zero value for its type (except for arrays; see above), it is omitted from the transmission.
And "false" is zero value. If you try to set t2.X = 0
it will show you the same behavior.
The unexpected behavior comes from reusing memory without cleaning it. You are reusing twice t and b which exposes you to many possible bugs. Here it's t that generates your problem but it could have been b too.
As answered by nvcnvn it's an expected behavior for gob encoding to not consider fields with 0 values in types. See encoded structures number of bytes gain in size: https://play.golang.org/p/HCz8-2kXHQX
If you want to reuse bytes.Buffer without any extra alloc and be safe, Reset it's values: https://golang.org/pkg/bytes/#Buffer.Reset