我一直在使用接口作为分层树。我们的想法是大声调用具体实现来调用.Children()
,.Father()
以及一个基于{id, FatherId}
模式片段自动填充层次结构的函数。
我只需要这个接口的三个不同的实现,也许为每个结构做整件事更方便但是我是Go的新手并且决定使用这个例子来理解接口。
我来到一个看起来像这样的界面:
type Node interface{
Equals(nodo *Node) bool
AddChild(child *Node)
SetFather(father *Node)
Children() []Node
Father() *Node
}
所以这个想法是调用Populate
函数:
func Populate(plainNodes []Node, HierarchichalNodes *[]Node) {}
普通节点是定义父亲身份的项目:
{id: "Animal", father: ""}
{id: "Plant", father: ""}
{id: "Mammals", father: "Animal"}
分层节点将是结果:
Animal
|__Mammals
Plant
我遇到的问题是当我尝试在具体结构中实现接口时,这种情况"Category"
。
type Category struct{
children []Category
father Category
}
func (c Category) SetFather(node *Node) {
v, ok = node.(*Category)
c.father = v
}
请注意,在Category
我希望与Category
父亲和孩子合作,而不是使用界面Node
。
我无法进行转换,我得到:
invalid type assertion: nodo.(*Category) (non-interface type *Node on left)
有什么想法吗?
答案 0 :(得分:3)
您的参数为node *Node
,其类型为*Node
。 Node
是一种接口类型,但*Node
不是:它是指向接口的指针。
不要使用指向接口的指针,很少需要它。而是将其更改为node Node
。同时将所有其他*Node
指针更改为Node
。
此外,如果Category.SetFather()
方法打算更改标识为接收方的Category
值,则它必须是指针,否则您最终只会更改将在{{1}之后丢弃的副本}返回。因此,请使用SetFather()
之类的接收器。
更进一步,如果c *Category
参数包含一个node
包含在接口中,则无法直接将其分配给*Category
,因为这是非指针类型{{1 }}。你需要一个指针间接,例如Category.father
;或者将Category
字段的类型更改为指针:c.father = *v
。
更正的father
方法可能如下所示:
father *Category
答案 1 :(得分:0)
这应该有效:
(*nodo).(Category)
首先取消引用,然后进行比较。