Interface 转到定义中使用该接口的接口

Interface 转到定义中使用该接口的接口,interface,go,Interface,Go,我在做斐波那契堆。(在我正在学习的一个算法类中多次提到它们,我想检查它们。)我希望堆使用任何类型的节点,因此我定义了一个节点接口: package node type Node interface { AddChild(other Node) Less(other Node) bool } type NodeList []Node func (n NodeList) AddNode(a Node) { n = append(n, a) } package main

我在做斐波那契堆。(在我正在学习的一个算法类中多次提到它们,我想检查它们。)我希望堆使用任何类型的节点,因此我定义了一个节点接口:

package node

type Node interface {
    AddChild(other Node)
    Less(other Node) bool
}

type NodeList []Node

func (n NodeList) AddNode(a Node) {
    n = append(n, a)
}
package main

import "container/list"
import node "./node"

type Element struct {
    Children *list.List
    Value int
}

func (e Element) AddChild(f Element) {
    e.Children.PushBack(f)
}

func (e Element) Less(f Element) bool {
    return e.Value < f.Value
}

func main() {
    a := Element{list.New(), 1}

    n := new(node.NodeList)
    n.AddNode(a)
}
(我使用[]节点数组,因为它与堆定义具有相同的影响。)如您所见,节点接口使用Node类型的参数定义其两个函数。这应该意味着函数必须接受实现节点接口的参数。堆的其余部分使用这些节点

在使用此堆的程序中,我创建了一个实现节点接口的类型:

package node

type Node interface {
    AddChild(other Node)
    Less(other Node) bool
}

type NodeList []Node

func (n NodeList) AddNode(a Node) {
    n = append(n, a)
}
package main

import "container/list"
import node "./node"

type Element struct {
    Children *list.List
    Value int
}

func (e Element) AddChild(f Element) {
    e.Children.PushBack(f)
}

func (e Element) Less(f Element) bool {
    return e.Value < f.Value
}

func main() {
    a := Element{list.New(), 1}

    n := new(node.NodeList)
    n.AddNode(a)
}
这里怎么了?显然元素没有正确实现接口,但我认为这是因为我是如何定义接口的。在围棋中有没有正确的方法来做我想做的事?接口可以指自己吗?

函数

func (e Element) Less(f Element) bool
与接口中的函数不匹配

func Less(other Node) bool
您需要实际匹配签名,如中所示

func (e Element) Less(f Node) bool
是的,这意味着可以向您传递一个
节点
,该节点不是
元素
。您必须在运行时进行测试,然后进行恐慌


作为一个为什么这样的例子,考虑你的代码是合法的,我试过如下:

type Other int
func (o Other) Less(f Other) bool {
    return o < f
}
func (o Other) AddChild(f Other) {}
e = GetSomeElement() // of type Element
var o Other
var n Node = e
fmt.Println(n.Less(o))
键入其他int
func(o其他)减去(f其他)布尔{
返回o

因为我将
元素
存储到
节点
类型的变量中,所以现在可以使用一个不是另一个
元素
的参数调用
Less()
,该参数违反了
元素.Less()的类型。这就是为什么这是不合法的。

哦。嗯,我想那不好玩。我希望我遗漏了一些东西,并且有一种方法可以让它只匹配接口类型。现在我想起来了,这没有什么意义,因为元素类型比节点类型更严格。我会使用
runtime
包来测试类型吗?@TSuds:不,您可以使用类型断言,如
other=f.(Element)
中所示。如果这个断言失败,它会为你惊慌。@ TSuds,考虑阅读,以便更好地理解接口是如何工作的(以及为什么没有一种类型比另一种更严格),正如你所期望的那样。