2013-11-23 12 views
5

背景埋め込みメソッドは "親"フィールドにアクセスできますか?

私はスペックの読み取りとコード・テストのかなりの量をやったと私は答えはノーだと思いますが、私は何が不足していないよ確認します。

ゴール

私はそれがどのように読める好きなので基本的に、私は、ゴーのためのActive RecordのスタイルのORMを作成しようとしているとどのようにそれはそのバックエンド・データ・ストアからである抽象化。私はむしろdata.Save(user)よりもuser.Save()を書くのは、ユーザーの構造体に共通のCRUDメソッドを埋め込むことです。

package main 

import (
    "fmt" 
    "reflect" 
) 

func main() { 
    test := Foo{Bar: &Bar{}, Name: "name"} 
    test.Test() 
} 

type Foo struct { 
    *Bar 
    Name string 
} 

func (s *Foo) Method() { 
    fmt.Println("Foo.Method()") 
} 

type Bar struct { 
} 

func (s *Bar) Test() { 
    t := reflect.TypeOf(s) 
    v := reflect.ValueOf(s) 
    fmt.Printf("model: %+v %+v %+v\n", s, t, v) 
    fmt.Println(s.Name) 
    s.Method() 
} 

http://play.golang.org/p/cWyqqVSKGH

質問

は、アクセス可能なトップレベルのフィールド(ゴーで正しい用語は、これら何のためにあるのかわからない)を作成する方法はあります埋め込み方法(例:s.Nameまたはs.Method()

新しいGopherにあなたの時間を寄付いただきありがとうございます。

+0

このスレッドに関する似たような質問の解決策をご覧ください:https://stackoverflow.com/questions/22153269/how-to-reflect-fields-of-containing-struct-from-a-method-of-the-embedded -struct?rq = 1 –

答えて

1

Goはあなたの後ろのものをサポートしていません。Testメソッドの受信者はBarポインターであり、埋め込まれているかどうかを判断する方法はありません。

本当にこのルートに行きたい場合は、interface{}のメンバーをBarに追加し、そのタイプを包含するタイプに設定する必要があります。このメンバを初期化することは、値を作成した者の責任であるか、または発信者に値をいくつかのORMメソッドに渡して設定するよう要求する可能性があります。これは特に綺麗ではありませんが、おそらくあなたができることは最高です。

このようにして、user.Save()ではなくdb.Save(user)とAPIを構成するのは本当に悪いですか?前者は複数のデータベースに拡張する明確な方法を提供しますが、後者はグローバルな状態に依存する可能性が高いようです。

+1

これはまさに私が取ったルートです。最初に投稿してから私は質問に答えませんが、答えを補うために私の解決策を提供します:http://play.golang.org/p/v7lC0swB3s。なぜ私は 'dbを避けたいのですか?(&user) 'を保存すると、アプリケーションによって管理される詳細が必要になります。 ORMの私のアイデアでは、アクティブなdbドライバを設定して忘れることができるので、モデルCRUDにできるだけ簡単に集中できるようになります。御時間ありがとうございます! – Brenden

+0

@Brendenあなたはこのリフレクションアプローチを実装しましたか?あなたはそれが十分に実行され、あなたはオーバーヘッドと "魔法"に満足していましたか? – Xeoncross

0

(私があなたの質問を正しく理解していれば)いいえ、埋め込みは継承ではありません。あなたが実際に何をしているかは、インターフェイスのように聞こえます。

type Saver interface { 
    Save() error 
} 

この場合、関連する当事者がそれを実装できます。

共通の構造体baseなどを使用して共通のメソッドを実装し、上位の構造体にそれぞれbaseを埋め込んで実装を共有できるようにすることができます。

+1

私は、インターフェイスを実装するすべての構造体に対してカスタム実装を行うことを避けたいと思います。 – Brenden

関連する問題