プラグインでのシンボリック インターフェイスの実装
Go プラグインでは、外部インターフェイスを持つプラグインをインポートすると、インターフェイスをプラグイン関数の応答。この動作は単純ではありませんが、プラグインの変数とインターフェイスを調べることで理解できます。
プラグイン変数のタイプ
プラグインの変数 (例: "Greeter")あなたの例では、宣言された型へのポインターとして存在します。したがって、Lookup 関数を使用すると、変数の値ではなく、変数へのポインターが返されます。これは、取得した値からインターフェイスを型アサートしようとするときに重要になります。
インターフェイスの型付け
インターフェイス (例: iface.IPlugin) を型アサートしようとするときそのインターフェースへのポインター (例: *iface.IPlugin) を指定すると、エラーが発生します。これは、インターフェイスへのポインター型の値が空のインターフェイス以外のインターフェイスを満たすことがないためです。
解決策
この問題を解決するには、次の 2 つの方法があります。
の逆参照ポインタ:
ポインタからインターフェイスへの型アサートの代わりに、最初にポインタを逆参照して値を取得してから、型アサーションを試行する必要があります。例:
pgPtr, ok := sym.(*iface.IPlugin) if !ok { panic(errors.New("error binding plugin to interface")) } pg := *pgPtr
関数の公開:
ポインター逆参照の複雑さを回避するには、プラグインで関数を公開することを検討してください。インターフェイスの実装を返します。プラグイン変数「Greeter」は、引数をとらず、iface.IPlugin を返す関数になります。
コード例
2 番目は次のとおりです。プラグインに実装されたアプローチ:
func Greeter() iface.IPlugin { return testpl{} }
および、対応する検索と使用法main プログラム:
Greeter, err := p.Lookup("Greeter") if err != nil { panic(err) } greeterFunc, ok := Greeter.(func() iface.IPlugin) if !ok { panic(errors.New("not of expected type")) } greeter := greeterFunc() fmt.Printf("You're now connected to: %s \n", greeter.WhatsYourName()) greeter.SayHello("user") greeter.SayGoodby("user")
このアプローチにより、プラグインからインターフェイス実装を取得するプロセスが簡素化され、ポインター処理の微妙な違いを避けることができます。
以上がGo プラグインからインターフェイスを正常に返すにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。