我正在尝试制作斐波那契堆。 (在我正在上的算法课中多次提到它们,我想检查一下。)我希望堆使用任何类型的节点,所以我定义了一个 Node 接口(interface):
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)
}
(我使用 []Node 数组是因为它与堆定义具有相同的效果。)如您所见,Node 接口(interface)定义了它的两个函数,其参数类型为 Node。这应该意味着函数必须接受实现 Node 接口(interface)的参数。堆的其余部分使用这些节点。
在使用这个堆的程序中,我创建了一个实现 Node 接口(interface)的类型:
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)
}
然而,这并没有奏效。编译器提示 Element 没有正确的接口(interface)函数定义。
cannot use a (type Element) as type node.Node in function argument:
Element does not implement node.Node (wrong type for AddChild method)
have AddChild(Element)
want AddChild(node.Node)
这里有什么问题?显然 Element 没有正确实现接口(interface),但我认为这是因为我如何定义接口(interface)。有没有正确的方法来做我想在 Go 中做的事情?接口(interface)可以引用自己吗?
最佳答案
函数
func (e Element) Less(f Element) bool
与界面上的功能不匹配
func Less(other Node) bool
您需要实际匹配签名,如
func (e Element) Less(f Node) bool
是的,这意味着您可以传递一个 Node
而不是 Element
。您必须在运行时对此进行测试并 panic 。
作为为什么会这样的例子,请考虑您的代码是否合法,我尝试了以下操作:
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))
因为我将 Element
存储到 Node
类型的 var 中,所以我现在可以调用 Less()
另一个 Element
,它违反了 Element.Less()
的类型。这就是为什么这样做不合法。
关于interface - Go Interfaces 使用定义中的接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13281191/