Skip to content

Not able to marshal a slice of large structs #235

@abiliojr

Description

@abiliojr

I'm trying to marshal an "heterogeneous" slice as an experiment (one of interfaces), and I'm hitting a wall with it. If I fill it with structs of up to 3 elements, it will encode them fine. If I add a single struct with 4 elements, it fails at runtime, saying:

msgp: type "main.FailureObject" not supported

FailureObject being the problematic struct in my example to reproduce the problem, though I proved I can marshal an individual object of that type.

Note: I intentionally need the objects to be encoded as arrays, and that's why I'm adding the "tuple" on top.

I'm completely new in Go, so most probably is my mistake. Anyhow, can you please take a look at the code:

package main

import "fmt"

//go:generate msgp
type ListOfObjects []interface{}

//msgp:tuple OkObject
type OkObject struct {
	A uint8
	B uint8
	C uint8
}

//msgp:tuple FailureObject
type FailureObject struct {
	A uint8
	B uint8
	C uint8
	D uint8
}

func AppendOkObj(list ListOfObjects, b uint8, c uint8) ListOfObjects {
	return append(list, OkObject{0, b, c})
}

func AppendFailureObj(list ListOfObjects, b uint8, c uint8) ListOfObjects {
	return append(list, FailureObject{1, b, c, 1})
}

func main() {
	// This will work. I can marshal a "long" object
	thisWorks := FailureObject{1, 2, 3, 4}
	res, _ := thisWorks.MarshalMsg(nil)
	fmt.Printf("% X\n", res)

	// I can do this and it will work
	list := make(ListOfObjects, 0, 10)
	list = AppendOkObj(list, 0, 0)
	list = AppendOkObj(list, 1, 1)
	list = AppendOkObj(list, 2, 2)
	res, _ = list.MarshalMsg(nil)
	fmt.Println("as you can see, it works")
	fmt.Printf("% X\n", res)

	// now this will give an error and instead return a half baked message
	list = make(ListOfObjects, 0, 10)
	list = AppendFailureObj(list, 0, 0)
	list = AppendFailureObj(list, 0, 0)
	res, err := list.MarshalMsg(nil)
	fmt.Println("as you can see, this doesn't")
	fmt.Printf("% X\n", res)
	fmt.Println(err)

	// combination of short and long won't work either
	list = make(ListOfObjects, 0, 10)
	list = AppendOkObj(list, 1, 1)
	list = AppendFailureObj(list, 0, 0)
	res, err = list.MarshalMsg(nil)
	fmt.Println("neither this")
	fmt.Printf("% X\n", res)
	fmt.Println(err)
}

If I'm assuming something here that is wrong, what would be the correct way, cleanest and most efficient way of encoding an array of arrays that can have different sizes and that are mapped to existing types.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions