[英]Golang type assertion with pointers
I've been working in an interface to use as a hierarchical tree.我一直在使用一个界面来用作分层树。 The idea is to aloud the concrete implementations to call
.Children()
, .Father()
and a function to auto populate the hierarchy based on a slice of {id, FatherId}
schema.这个想法是大声调用
.Children()
、 .Father()
的具体实现以及一个基于{id, FatherId}
架构切片自动填充层次结构的函数。
I only need three different implementations of this interface, maybe it's more convenient to do the whole thing for each struct but I'm new to Go and decided to use this example to understand interfaces.我只需要这个接口的三个不同的实现,也许为每个结构做整个事情更方便,但我是 Go 的新手,决定使用这个例子来理解接口。
I've come to an interface that looks something like this:我来到了一个看起来像这样的界面:
type Node interface{
Equals(nodo *Node) bool
AddChild(child *Node)
SetFather(father *Node)
Children() []Node
Father() *Node
}
So the idea is call a Populate
function:所以这个想法是调用一个
Populate
函数:
func Populate(plainNodes []Node, HierarchichalNodes *[]Node) {}
Plain nodes would be items defining the id of his father:普通节点将是定义他父亲 id 的项目:
{id: "Animal", father: ""}
{id: "Plant", father: ""}
{id: "Mammals", father: "Animal"}
Hierarchical nodes would be the result:结果是分层节点:
Animal
|__Mammals
Plant
The problem I'm getting is when I try to implement the interface in a concrete struct, this case "Category"
.我遇到的问题是当我尝试在具体结构中实现接口时,这种情况下为
"Category"
。
type Category struct{
children []Category
father Category
}
func (c Category) SetFather(node *Node) {
v, ok = node.(*Category)
c.father = v
}
Notice that in Category
I want to work with Category
father and children, not with interface Node
.请注意,在
Category
我想与Category
父亲和孩子一起工作,而不是与接口Node
。
I can't do the conversion, I get :我无法进行转换,我得到:
invalid type assertion: nodo.(*Category) (non-interface type *Node on left)
Any ideas?有什么想法吗?
Your parameter is node *Node
, it is of type *Node
.您的参数是
node *Node
,它的类型为*Node
。 Node
is an interface type, but *Node
is not: it is a pointer to interface. Node
是一种接口类型,但*Node
不是:它是一个指向接口的指针。
Don't use pointer to interface, it is very rarely needed.不要使用指向接口的指针,它很少需要。 Instead change it to
node Node
.而是将其更改为
node Node
。 Also change all your other *Node
pointers to just Node
.还将所有其他
*Node
指针更改为Node
。
Also if Category.SetFather()
method intends to change the Category
value identified as the receiver, it must be a pointer else you'd only end up changing a copy which will be discarded after SetFather()
returns.此外,如果
Category.SetFather()
方法打算更改标识为接收器的Category
值,则它必须是一个指针,否则您最终只会更改在SetFather()
返回后将被丢弃的副本。 So use a receiver like c *Category
.所以使用像
c *Category
这样的接收器。
Going further, if the node
argument contains a *Category
wrapped in an interface, you can't directly assign it to Category.father
as that is a non-pointer type Category
.更进一步,如果
node
参数包含包装在接口中的*Category
,则不能直接将其分配给Category.father
因为它是非指针类型Category
。 You need a pointer indirection, eg c.father = *v
;你需要一个指针间接,例如
c.father = *v
; or change the type of the father
field to be a pointer: father *Category
.或将
father
字段的类型更改为指针: father *Category
。
Corrected SetFather()
method could look like this:更正后的
SetFather()
方法可能如下所示:
func (c *Category) SetFather(node Node) {
if v, ok := node.(*Category); ok {
c.father = *v
}
}
This should work:这应该有效:
(*nodo).(Category)
De-reference first, assert afterwards.先取消引用,然后断言。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.