Based on the example JSON, it appears that you are attempting to create a recursive JSON structure. Recursive JSON (and recursive structs) are both very useful, but you have to make sure that you properly build them, or you can run into situations where the structure can not be created in memory.
Let us take a simple example:
type example struct {
itemOne int64
subElement example
}
When the program begins to create the struct in memory, it needs to figure out how large it needs to make it. That process goes as such:
- figure out how large to make itemOne.
- Add 8 bytes to the allocation space. (Total: 8)
- figure out how large to make subElement.
- figure out how large to make subElement-itemOne
- Add 8 bytes to the allocation space. (Total: 16)
- figure out how large to make subElement-subElement
- etc.
This process would continue forever until either 1: a stack overflow occurs in the program calculating the memory size, or 2: the total required memory was too large for the program.
In the case of Go, this situation actually has detection built in specifically, so the second step is actually never run. returning ./prog.go:7:6: invalid recursive type example for example.
The solution to this problem is to create a struct where the calculator knows the exact size of everything that it has to add to the struct. To do this, we take advantage of the fact that all structs have in common the size of the pointer to their location in memory.
type example struct {
itemOne int64
subElement *example
}
The addition of that single asterisk makes the recursive process from before finite.
- figure out how large to make itemOne.
- Add 8 bytes to the allocation space. (Total: 8)
- figure out how large to make subElement pointer.
- Add 8 bytes to the allocation space (Total 16)
- Clean up and allocate 16 bytes.
The values are then set to their defaults. Integers are set to zero, and pointers the nil value (also zero). Passing one of these into the json unmarshal would then create the exact structure you are looking for.
type sub struct {
Name string `json:"name"`
Desc string `json:"desc"`
Sub []*sub `json:"sub"`
}
full example
(Thanks to chmike for doing most of the heavy lifting/formatting for that example)
If you want to do some more digging into golang and pointers there are plenty of resources online such as the official documentation, which has some information spread around, or geeksforgeeks which is a bit more focused with examples. Just be aware of golang's automatic dereferencing
Sub *myStruct.Subfield represent zero or onemyStructs? or zero, one or more? If zero or one, then @BurakSerdar suggestion works. If more than one then use a slice.