I have a data structure like this:
type (
parent struct {
Items []*child
}
child struct {
Field string `json:"field"`
}
)
I also want parent
to have methods:
func (p *parent) example() { }
However the json requirement is that parent is just an array:
[
{
"field": "data"
}
]
I want parent
to be a simple array, but in order for parent
to have methods, it cannot be an array type.
Is there a way to solve both problems with one data structure?
(To make matters more complicated, the actual data structure I have to work with has two levels of this: greatgrandparent
contains []grandparent
, and grandparent
has a parent
that contains []child
. The json structure is externally defined, the arrays have no key names, and I would like methods on each of the four structs.)
CodePudding user response:
in order for parent to have methods, it cannot be an array type.
It can, it just MUST have a name because only named types (or pointers to named types) can implement methods. The following is valid Go code:
type parent []*child
func (p parent) example() { /* ... */ }
Note that the above parent
is a slice and not an array. Arrays in Go have static length, you cannot grow them and you cannot shrink them, slices on the other hand have dynamic length and you can resize them at will. Arrays and slices are closely related but not the same.
An alternative would be to have the struct type implement the json.Unmarshaler
/json.Marshaler
interfaces:
type parent struct { Items []*child }
func (p *parent) UnmarshalJSON(data []byte) error {
return json.Unmarshal(data, &p.Items)
}
func (p parent) MarshalJSON() ([]byte, error) {
return json.Marshal(p.Items)
}
The above will produce the required JSON structure.