我正在玩制作斐波那契堆.(我在算法类中多次提到它们,我想检查它们.)我希望堆使用任何类型的节点,所以我定义了一个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)
}
Run Code Online (Sandbox Code Playgroud)
(我使用[] 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)
}
Run Code Online (Sandbox Code Playgroud)
但是,这不起作用.编译器抱怨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)
Run Code Online (Sandbox Code Playgroud)
这有什么不对?显然,Element没有正确实现接口,但我认为这是因为我定义了接口.有没有正确的方法在Go中做我想要的?接口能参考自己吗?
功能
func (e Element) Less(f Element) bool
Run Code Online (Sandbox Code Playgroud)
与界面中的功能不匹配
func Less(other Node) bool
Run Code Online (Sandbox Code Playgroud)
您需要实际匹配签名,如
func (e Element) Less(f Node) bool
Run Code Online (Sandbox Code Playgroud)
是的,这意味着你可以通过一个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))
Run Code Online (Sandbox Code Playgroud)
因为我将其存储Element到var类型中Node,所以我现在可以Less()使用不是另一个的参数调用Element,这违反了类型Element.Less().这就是为什么这不合法.
| 归档时间: |
|
| 查看次数: |
152 次 |
| 最近记录: |