我正在制作斐波那契堆。(它们在我正在使用的算法类中多次提到,并且我想将它们检出。)我希望堆使用任何类型的节点,因此我定义了一个Node接口:package nodetype Node interface { AddChild(other Node) Less(other Node) bool}type NodeList []Nodefunc (n NodeList) AddNode(a Node) { n = append(n, a)}(我使用[] Node数组,因为它与堆定义具有相同的影响。)如您所见,Node接口使用Node类型的参数定义了它的两个函数。这应该意味着函数必须接受实现Node接口的参数。堆的其余部分使用这些节点。在使用此堆的程序中,我创建一个实现Node接口的类型:package mainimport "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没有正确的接口函数定义。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不能正确实现接口,但是我认为这是因为我定义接口的方式。在Go中有正确的方法来做我想做的事吗?接口可以引用自己吗?
1 回答
白板的微信
TA贡献1883条经验 获得超3个赞
功能
func (e Element) Less(f Element) bool
与界面的功能不匹配
func Less(other Node) bool
您需要实际匹配签名,如
func (e Element) Less(f Node) bool
是的,这意味着您可以通过Node而不是Element。您将必须在运行时进行测试,并且会出现恐慌。
作为为什么这样的一个示例,请考虑您的代码是否合法,并且我尝试了以下操作:
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类型的var中Node,所以现在我可以Less()用不是另一个Element违反了类型的参数来调用Element.Less()。这就是为什么这是不合法的。
- 1 回答
- 0 关注
- 193 浏览
添加回答
举报
0/150
提交
取消