I want to Marshal and Unmarshal a binary tree like structure in Go. Each node corresponds to a struct of type Node. Nodes are interconnected through pointers (left and right children), much like in a linked list. The tree's leaves carry content which is implemented as an interface. All leaves of a tree have the same type of Content which is known to the unmarshaler beforehand.
I know that when Unmarshaling a struct with an interface in one field (say "Content"), I have to do a type assertion likeerr = json.Unmarshal(byteSlice, &decodedStruct{Content: &MyStruct{}})
However, as the tree is of arbitrary size, my structs are deeply nested.
Is there a straightforward/idiomatic way of Marshaling/Unmarshaling such an object I am not aware of?
Below, I post a minimal example which I believe represents the two key features of first, a sequence of pointers and second, an interface at the "end". (playground: https://play.golang.org/p/t9C9Hn4ONlE )
// LinkedList is a simple linked list defined by a root node
type LinkedList struct {
Name string
Root *Node
}
// Node is a list's node with Content
type Node struct {
Child *Node
C Content
}
// Content is a dummy interface
type Content interface {
CalculateSum() int
}
// MyStruct implements Content
type MyStruct struct {
ID int
Values []int
}
// CalculateSum computes the sum of the slice in the field @Values
func (ms MyStruct) CalculateSum() (s int) {
for _, i := range ms.Values {
s += i
}
return
}
func main() {
// Make a list of three nodes with content in the leaf
ms := MyStruct{2, []int{2, 4, 7}}
leaf := Node{nil, ms}
node := Node{&leaf, nil}
rootNode := Node{&node, nil}
ll := LinkedList{"list1", &rootNode}
// Encoding linked list works fine...
llEncoded, err := json.Marshal(ll)
// ...decoding doesn't:
// error decoding: json: cannot unmarshal object into Go struct field Node.Root.Child.Child.C of type main.Content
llDecoded := LinkedList{}
err = json.Unmarshal(llEncoded, &llDecoded)
fmt.Println("error decoding: ", err)
}
ContentaMyStruct? If not, if you have more types implementingContent, how then do you know which leaf should be which type? And how do you plan on "telling" that to the unmarshaler? - mkoprivaNode.Cis always a*MyStruct? - Bayta Darell