関数の戻り値としてのプラグイン シンボル
Go では、両方のパッケージの外部で定義された共通インターフェイスを実装するプラグインをインポートできます。プラグインから構造体を返すとき、インターフェイスは正しく実装されます。ただし、インターフェイスを直接返そうとすると、Go のプラグイン システムの特定の技術的な理由で失敗します。
その理由は、プラグイン シンボルの性質にあります。 Plugin.Lookup() を使用してプラグインから Greeter という名前の変数を検索すると、その変数へのポインタが返されます。これは、プラグイン内の変数に変更を加えられるようにするために必要です。
sym に格納されている値の型を出力すると、それがインターフェイス (iface.IPlugin) へのポインターであるか、それともインターフェイスへのポインターであるかがわかります。実際のインターフェイス値 (iface.IPlugin)。プラグインが構造体を返す場合、sym に格納される値は iface.IPlugin を実装する main.testpl 型であるため、型アサーションは成功します。
ただし、プラグインが iface を返す場合は、 .IPlugin、sym に格納される値のタイプは *iface.IPlugin です。インターフェイス値へのこのポインターは、iface.IPlugin を含むインターフェイスを直接満たしません。したがって、型アサーションは失敗します。
この問題を回避するには、グローバル変数の代わりに Greeter インターフェイスを返す関数を公開するようにプラグインを変更できます。
func Greeter() iface.IPlugin { return testpl{} }
これは公開します。 func() iface.IPlugin 型の Greeter という名前のシンボル。 Plugin.Lookup() を使用して検索すると、関数ポインタが返されます。これにより、インターフェイス値へのポインターが不要になり、正しい型アサーションが可能になります。
greeterFunc, ok := GetFilter.(func() iface.IPlugin) if !ok { panic(errors.New("not of expected type")) } greeter := greeterFunc()
このメソッドは、インターフェイスを直接返すことに関連する落とし穴を回避しながら、プラグイン機能を公開するためのより明確で一貫したアプローチを提供します。プラグインから。
以上がGo プラグインがインターフェイスを直接返せないのはなぜですか?これはどのように解決できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。