2016-10-30 2 views
-2

実行時にリフレクションを使用して構造体のインタフェースまたはメソッドセットを生成することは可能ですか?例えばリフレクトでGoメソッドを生成する

type S struct { 
    a int 
} 

func (s *S) Fn(b int) int { 
    return s.a + b 
} 

type I interface { 
    Fn(a int) int 
} 

func main() { 
    var x I = &S{a: 5} 
    fmt.Printf("%#v\n", x.Fn) 
    fmt.Printf("%#v\n", reflect.TypeOf(x).Method(0)) 

    var y I 
    y.Fn = x.Fn // This fails, but I want to set y.Fn at runtime. 
    fmt.Printf("%#v\n", reflect.TypeOf(y).Method(0)) 
} 

https://play.golang.org/p/agH2fQ4tZ_

明確にするために、私はHTTPハンドラが含まれているインターフェースのでミドルウェアライブラリを構築しようとしていると私はREQのいくつかの並べ替えで、各ハンドラをラップしたいです/ response loggingので、新しいインターフェイスを返す必要があります。新しいインターフェイスの各関数が元の+いくつかのログをラップします。リフレクションを使用する必要はありませんIおよびJ.

type I interface { Fn1(a int) int } 
type J interface { Fn2(a int) int } 

type Y struct {  // Y implements I by calling fn 
    fn func(a int) int 
} 

func (y Y) Fn1(a int) int { return y.fn(a) } 

type Z struct {  // Z implements J by calling fn 
    fn func(a int) int 
} 

func (z Z) Fn2(a int) int { return y.fn(a) } 

var y I = Y{fn: x.Fn} 
var z J = Z{fn: x.Fn} 

ここ

+0

このシナリオで使用されるハンドラインターフェイスを記述します。それはhttp.Handlerなのでしょうか? –

+0

それはHTTPハンドラではないので、ハンドラのための素晴らしい汎用インタフェースはありません。基本的には、ミドルウェア・ライブラリがジェネリック・インタフェースIまたはJをサポートするようにしたい。そこにはメソッドのセットがあり、Jには別のメソッドがある。 – George

答えて

0

は、インターフェースのためにこれを処理する方法です。

playground example

+0

私はミドルウェアライブラリであるため、少し一般的にやろうとしています。 Fnを実装しているYをハードコードしないと可能でしょうか? – George

+0

Yは、Iの実装で任意の関数を呼び出すようにコーディングされています.Iを、http.Handlerまたはフレームワークが使用するインターフェイスに置き換えます。 –

関連する問題