2016-05-03 14 views
1

私はGoで継承を使用しようとしていますが、継承は(私が知る限り)技術的にはサポートされていませんが、匿名フィールドを使用して同様の機能を得ることができます。ここで'parent'構造体を受け入れる関数に 'child'構造体を渡す方法は?

は、私は2つの構造体全体では「継承」を定義しています方法は次のとおりです。

//Parent struct: 

type FSEntity struct { 
    guid GUIDNumber 
} 

//Child struct: 

type DataBlock struct { 
    FSEntity 
    data []byte 
} 

私は今、親構造体FSEntityのインスタンスを受け入れるようになっている、次のように定義された関数、持っている:

Put(entity FSEntity) {....} 

しかし、私はそうのような上Put関数に(継承によってもFSEntityである)DataBlockのインスタンスを渡してみてください。

上記の最後の行に
guidNumber := GUIDNumber(1234) 
value := []byte("sample string") 
dataBLock := DataBlock{FSEntity{guidNumber}, value} 

Put(dataBLock) 

、私はこのエラーを取得する:

cannot use dataBLock (type DataBlock) as type FSEntity in argument to Put 

は、どのように私はこれを解決するのですか?

答えて

7

私はあなたが使用している用語はあなたの問題を引き起こしていると思います。 putでは、単純に内部構造体を参照する必要があります。 Put(dataBLock.FSEntity)

ただし、明確にするために、ここでは親子関係はありません。あなたは埋め込みと呼ばれる言語機能を使用していて、合成のように動作します(つまり、あるタイプは他のタイプで構成されます)。埋め込むものだけが埋め込み範囲にフィールド/メソッドを持ちます。そのため、タイプを継承するときのように多態的な振る舞いがないので、あなたは '子'と呼ばれる型を渡すことができません。代わりに、型はそれで構成されていますが、インダイレクションの余分なレベル。あなたのメソッドは、埋め込み型を引数として受け入れるので、それを明示的に参照するだけでそれを渡す必要があります。外側の構造体は決してその型ではありません。

+0

説明をありがとう。だから、Goには適切な継承を使用する方法はありません。私が望む機能は 'Put()'の中にあったため、BOTHクラスの変数にアクセスすることができました。単にPut(dataBLock.FSEntity)を実行すれば可能になりません – Ahmad

+1

@Ahmadあなたの両方の構造体の変数にアクセスできるようにするには、 'Put'の定義を更新しなければならないので、引数は' DataBlock'型です。 Goには継承はありません。あなたは少し違って問題について考える必要があります。多態性が言語のコンセプトとして存在しないときは、それを活用しようとしています。そのタイプの動的な振る舞い(いくつかの共通の動作/フィールド/ ectを持つと思われる多くの型を含むコレクションなど)が必要な場合は、それをインタフェースの背後で抽象化します。 – evanmcdonnal

0

これを解決する最も簡単な方法は、パラメータの型:pass a FSEntityを満たすことです。それを埋め込んでいる構造体からFSEntityを取得する必要がある場合は、単にdataBlock.FSEntityを実行することができます。

//Parent struct: 

type FSEntity struct { 
    guid string 
} 

//Child struct: 

type DataBlock struct { 
    FSEntity 
    data []byte 
} 

func main() { 
    myVar := DataBlock{} 
    myVar.guid = "test" 
    myVar.data = []byte("moar test") 
    a(myVar.FSEntity) 
} 

func a(x FSEntity) { 
    fmt.Printf("%+v\n", x) 
} 

Go playground

+0

しかし、私が望む機能は、Put内では、 '子'構造体変数にアクセスできることです。あなたのコードが構造化されているので、私はそれが可能だとは思わない。 – Ahmad

2

それは継承とアイデアがデータブロックは、この方法

dataBLock.Put() 
0
package main 

import (
    "fmt" 
) 

type Guider interface { 
    Guid() string 
} 
type FSEntity struct { 
    guid string 
} 
func (e FSEntity) Guid() string { 
    return e.guid 
} 

//Child struct: 

type DataBlock struct { 
    FSEntity 
    data []byte 
} 

func main() { 
    myVar := DataBlock{} 
    myVar.guid = "test" 
    myVar.data = []byte("moar test") 
    Put(myVar) 
} 

func Put(x Guider) { 
    fmt.Printf("%+v\n", x) 
} 

アンを使用することができます

type DataBlock struct { 
    FSEntity 
    data []byte 
} 

を埋め込んだ後、メソッド

func (entity FSEntity) Put() {....} 

として入れて定義することで、正確ではありませんインターフェイスはあなたがaccに役立つでしょう親構造体をeptする

関連する問題