埋め込みメソッドは親フィールドにアクセスできますか?
Go では、埋め込みメソッドはコードの再利用と編成のための強力なメカニズムです。ただし、一般的な疑問が生じます: 埋め込みメソッドは親構造体のフィールドに直接アクセスできますか?
Background
コンテキストとして、アクティブ レコードを作成していると仮定します。 Go 用のスタイル ORM では、可読性と抽象化のために一般的な CRUD メソッドがユーザー構造体に埋め込まれています。これにより、data.Save(user).
Example
の代わりに user.Save() を記述できるようになります。次のコード スニペットを考えてみましょう:
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() }
質問の再検討
当面の質問埋め込みメソッドからトップレベルのフィールドにアクセスできるようにする方法があるかどうかです。上の例では、Test メソッドが Bar に埋め込まれており、親 Foo 構造体から Name フィールドにアクセスしようとしています。
Answer
残念ながら、Go には提供されていません。埋め込みメソッドが親構造体のフィールドにアクセスするための直接メカニズム。 Test メソッドのレシーバーは Bar へのポインターであり、それが埋め込まれているかどうかを Go が判断する方法はありません。
考えられる解決策
実現するにはこの機能を使用する場合、考えられる回避策の 1 つは、Interface メンバーを Bar 構造体に追加し、それを実装する型がメンバーを包含型に設定することを要求することです。{}このメンバーの初期化は、呼び出し元が行うことも、ORM メソッドを通じて処理することもできます。ただし、このアプローチでは、さらなる複雑さと潜在的なメンテナンスの問題が発生します。
代替の観点
あるいは、API を db.Save(user) として構造化できない可能性を考慮してください。見た目と同じくらい有害です。このアプローチは、複数のデータベースをサポートする簡単な方法を提供し、グローバル状態への依存を回避します。
以上が埋め込み Go メソッドは親構造体のフィールドにアクセスできますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。