【发布时间】:2020-10-30 03:34:44
【问题描述】:
我想在 Go 中编组和解组类似二叉树的结构。每个节点对应一个 Node 类型的结构。节点通过指针(左右子节点)相互连接,就像在链表中一样。树的叶子承载着作为接口实现的内容。一棵树的所有叶子都具有相同类型的内容,这是解组器事先知道的。
我知道,当在一个字段中解组具有接口的结构(例如“内容”)时,我必须进行类型断言,例如err = json.Unmarshal(byteSlice, &decodedStruct{Content: &MyStruct{}})
然而,由于树的大小是任意的,我的结构是深度嵌套的。
是否有一种直接/惯用的方式来编组/解组我不知道的此类对象?
下面,我发布了一个最小的示例,我认为它代表了两个关键特征:第一个是指针序列,第二个是“末端”的接口。 (操场: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)
}
【问题讨论】:
-
每个
Content都是MyStruct吗?如果没有,如果你有更多类型实现Content,那么你怎么知道哪个叶子应该是哪个类型?您打算如何将这些“告诉”解组器? -
@mkopriva:感谢您的提问。我应该提到这一点并相应地修改了帖子。
-
@jppade: ??我没有问任何问题。
-
@jppade 你是说
Node.C中的具体值总是*MyStruct? -
@MuffinTop 不,它可以是任何实现内容的东西。但我知道编组/解组时它是什么类型。
标签: pointers go interface linked-list unmarshalling