4

私はフィボナッチヒープを作って遊んでいます。(それらは、私が取っているアルゴリズム クラスで何度か言及されており、それらをチェックしたいと思います。) ヒープで任意の種類のノードを使用する必要があるため、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 型の引数を持つ 2 つの関数を定義します。これは、関数が 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でやりたいことをする正しい方法はありますか? インターフェイスは自分自身を参照できますか?

4

1 に答える 1

6

関数

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を型の変数に格納したので、別の型ではない引数を使用してNode呼び出すことができます。これは、の型に違反します。これが合法ではない理由です。Less()ElementElement.Less()

于 2012-11-08T01:45:10.970 に答える