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

时间:2012-11-08 01:36:26

标签: interface go

我正在玩制作斐波那契堆。 (我在算法类中多次提到它们,我想检查它们。)我希望堆使用任何类型的节点,所以我定义了一个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)
}

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

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

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没有正确的接口函数定义。

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 个答案:

答案 0 :(得分:6)

功能

func (e Element) Less(f Element) bool

与界面

中的功能不匹配
func Less(other Node) bool

您需要实际匹配签名,如

func (e Element) Less(f Node) bool

是的,这意味着你可以传递一个不是Node的{​​{1}}。你必须在运行时和恐慌时测试它。


作为一个例子,为什么会这样,考虑你的代码是否合法,我尝试了以下内容:

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。这就是为什么这不合法。