Struct の組み込みインターフェイスを使用した Go リフレクション
「実際の」関数の検出
Go のリフレクションパッケージは、実行時に型と値に関する情報へのアクセスを提供します。これは強力なツールですが、構造体内の組み込みインターフェイスを操作する場合は混乱を招く可能性もあります。
次の例を考えてみましょう。
type A interface { Foo() string } type B struct { A bar string }
ご覧のとおり、Go は次のことを行いません。コンパイル時に埋め込みインターフェイスの実装を強制します。これは、実装を提供せずにインターフェイスを構造体に埋め込むことができることを意味します。
メソッドにアクセスするためのリフレクションの使用
リフレクション パッケージを使用して、オブジェクトからメソッドを取得できます。実装が提供されていない場合でも、構造体の埋め込みインターフェイス:
bType := reflect.TypeOf(B{}) bMeth, has := bType.MethodByName("Foo") if has { fmt.Printf("HAS IT: %s\n", bMeth.Type.Kind()) res := bMeth.Func.Call([]reflect.Value{reflect.ValueOf(B{})}) val := res[0].Interface() fmt.Println(val) } else { fmt.Println("DOESNT HAS IT") }
ただし、埋め込みインターフェイスに実装がない場合、このコードはパニックになる可能性があります。
実装の不在の検出
埋め込みインターフェイスに実装がないかどうかを検出するには、関数へのポインタをチェックできます。匿名インターフェイス値の関数テーブル内:
b := B{} bType := reflect.TypeOf(b) bMeth, has := bType.MethodByName("Foo") if has { bMethPtr := bMeth.Func.Pointer() if bMethPtr == 0 { fmt.Println("No implementation") } else { fmt.Println("Implementation found") } } else { fmt.Println("Interface not embedded") }
関数へのポインターが 0 の場合、関数は存在しません。 実装。それ以外の場合は、実装が存在します。
代替アプローチ
より単純なアプローチも使用できます:
if b.A != nil { b.Foo() }
組み込みインターフェースが設定されている場合nil に設定すると、b.Foo() 呼び出しがパニックになります。それ以外の場合は、実装 (存在する場合) が実行されます。
以上がGo 構造体の埋め込みインターフェイスにリフレクションを使用した関数実装があるかどうかを確実に検出するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。