13

Goのインターフェイスを使用してRPCスタイルのインターフェイスを定義することを考えています。したがって、特定のサービスに対して、次のようなインターフェイスを作成する場合があります。

type MyService interface{
  Login(username, password string) (sessionId int, err error)
  HelloWorld(sessionId int) (hi string, err error)
}

私がやりたいのは、リフレクションを使用してそのインターフェイスを実装し、メソッド呼び出しをRPC呼び出しに変換し、入力パラメーターをマーシャリングし、結果をアンマーシャリングしてメソッドの出力に戻すことです。入力パラメータの[]interface{}を取得できれば、リフレクションを使用してサービスを呼び出すことができます。ただし、リフレクションを使用して、リフレクションを使用する関数を呼び出してインターフェイスを実装する値を動的に作成する方法がわかりません。安全でないものを使用していても、これを行う方法を知っている人はいますか?

4

4 に答える 4

11

そのタイプのオブジェクトをインスタンス化するため、リフレクションを介してメソッドが添付されたタイプを作成することはできません。

パッケージを介して多くのハッキングを行うことで、これを達成できる可能性がありunsafeます。しかし、それでも、それは大きな痛みになるでしょう。

解決しようとしている問題について詳しく説明すれば、コミュニティはそれを解決する別の方法を思いつくかもしれません。

編集 (2015 年 7 月 23 日): Go 1.5以降では、 と がreflect.FuncOfありreflect.MakeFunc、まさにあなたが望むことを行います。

于 2012-09-13T11:53:10.977 に答える
7

Reflectパッケージは、Go 1.1 で任意に型指定された新しい関数を作成する機能を獲得するようです: Reflect.MakeFunc

(以下は @nemo への返信として追加)

インターフェイスの代わりに、構造体型を作成できます。

type MyService struct{
  Login func(username, password string) (sessionId int, err error)
  HelloWorld func(sessionId int) (hi string, err error)
}

autorpc.ImplementService(&MyService, MyServiceURL)
session, err := MyService.Login(username, password)
stringout, err := MyService.HelloWorld(session)
于 2012-12-05T16:19:56.620 に答える
0

インターフェースを完全に実装できれば、あなたが望むことを達成できるかもしれないと思いますがreflect.Type、それはできません(エクスポートされていないメソッド)。次に、を使用してカスタムタイプをインスタンス化できる可能性がありますunsafe_New

全体として、そうするのは良い考えではありません。

あなたが望むものの次善の策はおそらくgobのようなものを使うことです。gobを中間言語として使用し、リフレクションを使用してインターフェースからメソッドを読み取り、それらをgobとして記述し、作成されたgobコードを実際のGoオブジェクトにデコードできます。しかし、それが価値があるかどうかはわかりません。

ほとんどの場合、クライアント側でインターフェイスを手動で実装し、メソッド呼び出しを転送することで、より安全になります。

于 2012-09-13T12:15:19.830 に答える
0

言語の静的な性質のため、現時点では Go でインターフェイスを動的に実装する方法はありません。

私はあなたが達成したいことを理解しており、より高度なリフレクション機能の恩恵を受ける他のシナリオもあります (例: 単体テスト用の優れたモック フレームワーク)


とはいえ、この問題を回避する方法はあります。インターフェイスの特定の RPC 実装を含む Go ソース コード ファイルを生成する独自のツールを作成できます。

ソース インターフェイスを解析および処理するには、 ASTライブラリなどを使用する必要があります。

そのパス ( gostubツール; 参照として使用できます) をたどると、それはまったく楽しく簡単ではないと言えます。それでも、Go はgo:generate機能を提供するため、最終的な結果は耐えられます。これにより、少なくともインターフェイスが変更された後、ツールの再実行が少し簡単になります。

于 2015-07-22T18:55:23.790 に答える