2016-10-05 10 views
1

私は階層ツリーとして使うためにインターフェイスで作業してきました。アイデアは、.Children().Father()と呼び、{id, FatherId}スキーマのスライスに基づいて階層を自動入力する機能を念頭に置いています。Golang型アサーションでポインタを使用

私はこのインターフェイスの3つの異なる実装を必要とします。それぞれの構造体全体を処理する方が便利かもしれませんが、Goを初めて使っていて、インターフェイスを理解するためにこの例を使用することに決めました。

私は次のようになりますインターフェイスに来ている

:プレーンノードは、彼のIDを定義する項目になり

func Populate(plainNodes []Node, HierarchichalNodes *[]Node) {} 

:だからアイデアはPopulate関数を呼び出している

type Node interface{ 
    Equals(nodo *Node) bool 
    AddChild(child *Node) 
    SetFather(father *Node) 

    Children() []Node 
    Father() *Node 
} 

父:

{id: "Animal", father: ""} 
{id: "Plant", father: ""} 
{id: "Mammals", father: "Animal"} 

階層型ノードは、結果:

Animal 
|__Mammals 

Plant 

具体的な構造体にインターフェイスを実装しようとすると、このケースが発生します。

type Category struct{ 
    children []Category 
    father Category 
} 

func (c Category) SetFather(node *Node) { 
    v, ok = node.(*Category) 
    c.father = v 
} 

Categoryに私はCategory父親と子供とではなく、インタフェースNodeで仕事をしたいということに注意してください。

私は、変換を行うことはできません、私が取得:

invalid type assertion: nodo.(*Category) (non-interface type *Node on left) 

任意のアイデア?

+0

あなたはポインタをインターフェイスとして渡しません。 '* Category'へのポインタは' Node'へのポインタではなく 'Node'です。 –

答えて

2

パラメータはnode *Nodeです。タイプは*Nodeです。 Nodeはインターフェイスタイプですが、*Nodeはそうではありません。インターフェイスへのポインタです。

インターフェイスへのポインタを使用しないでください。非常にめったに必要ありません。代わりにnode Nodeに変更してください。他の*NodeポインタもすべてNodeに変更してください。

またCategory.SetFather()方法は受信機として識別Category値を変更しようとするならば、それはあなたがSetFather()復帰した後に廃棄されるコピーを変更するだけで終わるだろうと他のポインタでなければなりません。したがって、c *Categoryのような受信機を使用してください。さらに行く

node引数はインターフェイスに包まれ*Categoryが含まれている場合には非ポインタ型Categoryであるとして、あなたは直接Category.fatherに割り当てることができません。ポインタの間接参照が必要です(例: c.father = *v; fatherフィールドのタイプをポインタに変更する:father *Category

修正しSetFather()方法は次のようになります。

func (c *Category) SetFather(node Node) { 
    if v, ok := node.(*Category); ok { 
     c.father = *v 
    } 
} 
+0

SetFatherを(ポインタ?)インターフェイスのメソッドにする方法を教えてください。 – Marcos

+0

@Marcos 'SetFather()'メソッドを 'Node'の下に置くと' Node'インターフェースのメソッドになります。 'func(c * Category)SetFather(node Node)'メソッドを宣言すると、この 'SetFather()'は '* Category'(受信者)型のメソッドになります。したがって、 'Node'の他のすべてのメソッドで同じことをすると、' * Categroy'型は 'Node'を実装するので、' Node'型の変数に '* Category'型の値を代入することができます。 – icza

+0

インターフェイスへのポインタが頻繁に使用されます。 Goのhttp-packageはそれらなしでは動作しません。 – marsbear

0

これは動作するはずです:

(*nodo).(Category) 

逆参照最初に、その後の比較します。

関連する問題