带有指针的 Golang 类型断言

Posted

技术标签:

【中文标题】带有指针的 Golang 类型断言【英文标题】:Golang type assertion with pointers 【发布时间】:2017-02-13 20:39:15 【问题描述】:

我一直在研究一个用作分层树的界面。这个想法是大声说出具体的实现来调用.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 的项目:

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)

有什么想法吗?

【问题讨论】:

你不应该将接口作为指针传递。指向*Category 的指针是Node,而不是指向Node 的指针。 【参考方案1】:

你的参数是node *Node,它的类型是*NodeNode 是一个接口类型,但*Node 不是:它是一个指向接口的指针。

不要使用指向接口的指针,它很少需要。而是将其更改为node Node。还将所有其他 *Node 指针更改为 Node

此外,如果Category.SetFather() 方法打算更改标识为接收者的Category 值,则它必须是一个指针,否则您最终只会更改将在SetFather() 返回后丢弃的副本。所以使用像c *Category这样的接收器。

更进一步,如果node 参数包含封装在接口中的*Category,则不能直接将其分配给Category.father,因为它是非指针类型Category。你需要一个指针间接,例如c.father = *v;或者将father字段的类型改为指针:father *Category

更正后的SetFather() 方法可能如下所示:

func (c *Category) SetFather(node Node) 
    if v, ok := node.(*Category); ok 
        c.father = *v
    

【讨论】:

如何使 SetFather 成为(指针?)接口的方法? @Marcos 当你在Node 下列出SetFather() 方法时,它将是Node 接口的方法。当您声明func (c *Category) SetFather(node Node) 方法时,此SetFather() 将成为*Category 类型的方法(接收者)。因此,如果您对Node 的所有其他方法执行相同操作,则*Categroy 类型将实现Node,因此*Category 类型的值可以分配给Node 类型的变量。 经常使用指向接口的指针。没有它们,Go 的 http-package 将无法工作。 只是不要在函数头中写 node *Node (但如果你想使用指针,请将指针保留在其他地方)。【参考方案2】:

这应该可行:

(*nodo).(Category)

先去引用,后断言。

【讨论】:

以上是关于带有指针的 Golang 类型断言的主要内容,如果未能解决你的问题,请参考以下文章

Golang 类型断言

golang类型断言

golang类型断言的使用(Type Assertion)

golang 类型断言使用 reflect.Typeof()

Golang type assertion 类型断言

Golang type assertion 类型断言