2017-08-27 11 views
-2

私は定期的に親構造体のメソッドを呼び出す必要がありますが、呼び出されると、埋め込み構造体固有の拡張プロパティを更新する必要があります(私の場合、データ型)。親からのメソッドを使用して埋め込み構造体のプロパティを変更する

私が考えることができる唯一の解決策は、定期的なメソッドが再び呼び出されると、親の元のデータではなく埋め込まれた構造体のメソッドを使用するように親構造体のメソッドをオーバーライドすることでした。次のように

コードが見えます:

package main 

import (
    "fmt" 
) 

type Fruit struct { 
    image *Image 
    tree *Tree 

    SetImage func(*Image) 
    SetTree func(*Tree) // #2 (always nil for Strawberry) 
} 

func NewFruit() *Fruit { 
    f := &Fruit{} 
    f.SetImage = f.setImage 
    f.SetTree = f.setTree 
    return f 
} 

func (f *Fruit) Image() *Image { 
    return f.image 
} 
func (f *Fruit) Tree() *Tree { 
    return f.tree 
} 

func (f *Fruit) setImage(i *Image) { 
    f.image = i 
} 
func (f *Fruit) setTree(t *Tree) { 
    f.tree = t 
} 

type Strawberry struct { 
    *Fruit 
    id int 
} 

func NewStrawberry(f *Fruit) *Strawberry { 
    strawberry := &Strawberry{Fruit: f} 
    return strawberry 
} 
func (s *Strawberry) SetID(i int) { 
    s.id = i 
} 
func (s *Strawberry) ID() int { 
    return s.id 
} 
func (s *Strawberry) setImage(i *Image) { 
    s.id = 6 
    s.image = i 
} 

type Kiwi struct { 
    *Fruit 
    id string 
} 

func NewKiwi(f *Fruit) *Kiwi { 
    kiwi := &Kiwi{Fruit: f} 
    return kiwi 
} 
func (k *Kiwi) SetID(i string) { 
    k.id = i 
} 

func (k *Kiwi) ID() string { 
    return k.id 
} 
func (k *Kiwi) setImage(i *Image) { 
    k.id = "abc" 
    k.image = i 
} 
func (k *Kiwi) setTree(t *Tree) { 
    k.tree = t 
} 

type Image struct { 
    path string 
} 

type Tree struct { 
    height int 
} 

func main() { 
    f := NewFruit() 
    f.SetImage(&Image{"kiwi1.jpg"}) 

    /*s := NewStrawberry(f) 
    s.SetImage = s.setImage 
    fmt.Println(s, s.ID(), s.Image()) 
    f.SetImage(&Image{"strawberry.jpg"}) 
    fmt.Println(s, s.ID(), s.Image())*/ 

    k := NewKiwi(f) 
    k.SetImage = k.setImage 
    k.SetTree = k.setTree 
    fmt.Println(k, k.ID(), k.Image()) 
    f.SetImage(&Image{"kiwi2.jpg"}) 
    f.SetTree(&Tree{2}) 
    fmt.Println(k, k.ID(), k.Image(), k.Tree()) 
} 

上記のコードは、仕事をしている間、私は2つの懸念などを必要とするFruit親構造体を持っています。その必要SetXXX(*XXX)の方法と10個の追加プロパティ:

  1. その後、すべての埋め込まれた構造体は、新しい親構造体のメソッドを反映するために更新する必要があります。これは、プロパティごとに必要なコーディングの多くのようです。

  2. これらの埋め込み構造体の中には、いくつか残っているプロパティメソッドのすべてを必要としないものもあります。nilすべての果物が木の上で生育するわけではないという良い例です。コメント#2の資産を残してくださいStrawberryのために役に立たない。

これらの懸案事項はどちらも有効ですが、避ける方法はありますか?

P.S. アプリケーションは多くの処理スループットを必要とするので、リフレクションとタイプアサーションの過度使用(すべてのプロパティを作成することはできません。interface{})を使用せずに、コードは型安全で最適なものにするのが理想的です。

答えて

2

これらの懸案事項はどちらも有効ですが、避ける方法はありますか?

いいえはい。

ちょうど慣用のGOを書いてを入力しないでください。 Goに伝統的なOOを書き込もうとします。例えば。セッターとゲッターはゴーでは一般的ではありません。そして、親子関係として埋め込むことをやめてください。

+0

どうやって書かれているのか分かりません(慣用的なGoの方法)。私の質問の最初の文に記載されている問題を解決する反例を提供してください。 より良い単語がないため、私は 'parent'を使いました。 –

+1

@FanusduToit "新しい親構造体メソッドを反映するために、すべての埋め込み構造体を更新する必要があります"と書いてありますが間違っています。構造体埋め込みはメソッドを促進する。埋め込み型にメソッドがある場合、埋め込み型のメソッドセットはこのメソッドによって拡張されます(技術的な詳細があります)。この無意味なセッターズを取り除き、メソッドセットに焦点を当てたhttps://golang.org/ref/spec#Struct_typesを読んでください。 – Volker

+1

あなたの最後のコメントは、最初の答えよりはるかに良い答えです。私はなぜあなたが実際に私がなぜそれを理解するのを助けたので、私の 'セッターズ 'が役に立たないのか理解しています。ありがとうございました! –

関連する問題