Home > Blockchain >  How to serialize slice of fixed length data structure in Go
How to serialize slice of fixed length data structure in Go

Time:11-25

The following code generates panic: binary.Write: invalid type main.test:

type (
    config struct {
        Key uint16
        Val uint16
    }
    test struct {
        Mode uint32
        Data []config
    }
)

func main() {
    t := test{
        Mode: 5,
        Data: []config{
            {1, 2},
            {3, 4},
        },
    }
    var bs bytes.Buffer
    assert(binary.Write(&bs, binary.LittleEndian, t))
}

The key point is:

  1. length of the config data structure is fixed, but the test structure contains a slice of config, whose number varies.
  2. I need to interact with other program written in C, so cannot use things like GOB.

Is there anyway to binary-encode such data structure, apart from do it manually?

CodePudding user response:

The problem is not writing out a slice, as slices are supported. Quoting from binary.Write():

Write writes the binary representation of data into w. Data must be a fixed-size value or a slice of fixed-size values, or a pointer to such data.

The problem is that the size of config is not fixed. It is not fixed because it contains a field of slice type, and the binary representation of the slice is not fixed (depends on its length).

So writing a slice value is supported, writing a value of composite type (e.g. struct) holding a slice is not supported for the above mentioned reason.

You may change the field to an array type (e.g. [2]config) but I assume this isn't sufficient to you.

You may write the fields using encoding/binary individually, in which case you can write a slice value.

For example:

var bs bytes.Buffer
fmt.Println(binary.Write(&bs, binary.LittleEndian, t.Mode))
fmt.Println(binary.Write(&bs, binary.LittleEndian, t.Data))

This will output (try it on the Go Playground):

<nil>
<nil>

There was a proposal to extend encoding/binary to support similar cases (see here), but was rejected. encoding/binary is for simple things.

If you need more flexibility, use encoding/gob (although Go specific), or use encoding/json (supported by all languages).

  •  Tags:  
  • go
  • Related