Go Interfaces that use an interface in the definition

I play with creating a Fibonacci heap. (They are mentioned several times in the class of algorithms that I accept, and I want to test them.) I want the heap to use any nodes, so I define the 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) } 

(I use the [] Node array because it has the same effect as the heap definition.) As you can see, the Node interface defines two of its functions with arguments of type Node. This should mean that functions must accept arguments that implement the Node interface. The rest of the heap uses these nodes.

In a program that uses this heap, I create a type that implements the 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) } 

However, this did not work. The compiler complains that Element does not have the correct function definitions for the 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) 

What is wrong here? Obviously, Element does not implement the interface correctly, but I think this is because of how I defined the interface. Is there a proper way to do what I want in Go? Can interfaces refer to themselves?

+4
source share
1 answer

Function

 func (e Element) Less(f Element) bool 

does not match function from interface

 func Less(other Node) bool 

In fact, you have to match the signature, as in

 func (e Element) Less(f Node) bool 

And yes, that means that Node , which is not an Element can be passed to you. You will have to test this at runtime and panic.


As an example of why this is so, consider whether your code was legal, and I tried the following:

 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)) 

Since I saved Element to var of type Node , now I can call Less() with an argument that is not another Element , which violates the type of Element.Less() . That is why it is not legal.

+6
source

Source: https://habr.com/ru/post/1444711/


All Articles