Struct の組み込みインターフェイスを使用した Go リフレクション: 「実際の」関数の決定
Go のリフレクション パッケージのコンテキストで、構造体の動作を理解する匿名インターフェイスが埋め込まれたフィールドは非常に重要です。次のコード スニペットを考えてみましょう。
type A interface { Foo() string } type B struct { A bar string }
B がインターフェイス A を実装する必要があると仮定するのは直感的ですが、Go の動的な性質により、別の解釈も可能です。 B に埋め込まれた匿名インターフェイス値は、他の構造体フィールドと同様に、フィールドとして機能します。
リフレクションを使用すると、次のように B の型からメソッドを取得できます。
bType := reflect.TypeOf(B{}) bMeth, has := bType.MethodByName("Foo")
ただし、 bMeth の場合、B の「実際の」関数実装の存在は保証されません。あなたが遭遇したようなパニックを回避するには、B に対して定義された実際の関数があるかどうかを判断する方法が必要です。 B.
実装の不在の検出
「実際の」関数と継承されたインターフェイス メソッドを区別する鍵は、埋め込まれた匿名メソッドのインターフェイスの側面にあります。インタフェース。構造体に明示的な実装が存在しない場合、インターフェイス メソッドは組み込みインターフェイスから効果的に継承されます。
実際の関数の存在を確認するには:
if bMeth.Type.NumIn() == 1 && bMeth.Type.NumOut() == 1 { fmt.Println("Real function found") } else { fmt.Println("Interface method inherited") }
このチェックでは、数値が検査されます。取得されたメソッドの入力パラメータと出力パラメータ。両方とも 1 の場合、メソッドは 1 つのレシーバー パラメーター (B インスタンス) を受け入れ、1 つの値を返すため、そのメソッドが「実際の」関数実装であることを示します。それ以外の場合、これらの数値が異なる場合、メソッドはインターフェイスから継承されます。
代替アプローチ: 型の切り替え
リフレクションを使用する代わりに、型の切り替えを使用して、選択的にb.A の動的タイプに基づいて実行します。 b.A が nil の場合、「実際の」実装が存在しないことを示します。
switch b.A.(type) { case nil: fmt.Println("No function implementation in B") default: fmt.Println("Function implementation found") }
結論
埋め込まれた匿名インターフェイスの性質を理解し、いずれかのリフレクションを採用することによってカスタム チェックまたは型切り替えを使用すると、インターフェイス メソッドを継承する構造体フィールドの「実際の」関数の存在を効果的に判断できます。
以上が組み込みインターフェイスを備えた Go 構造体に、リフレクションを使用した「実際の」関数実装があるかどうかを確認するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。