Go の関数ラッパー
質問:
で関数ラッパーを作成するにはどうすればよいですか?関数の前後にコードを挿入する実行?
答え:
Go では、関数を引数として受け取り、新しい関数値を返す関数ラッパーを作成できます。これにより、ラップされた関数の呼び出しの前後にコードを挿入できます。
ラッパー関数の例を次に示します:
func funcWrapper(myFunc interface{}) { fmt.Println("Before") // Call myFunc fmt.Println("After") }
署名付きラップ関数:
ラップされる関数のシグネチャがわかっている場合は、その関数値を受け取るラッパー関数を作成できます。型を取得し、同じ型の別の関数値を返します。これは以下に例を示します:
func wrap(f func(i int) int) func(i int) int { return func(i int) (ret int) { fmt.Println("Before, i =", i) ret = f(i) fmt.Println("After, ret =", ret) return } }
複数の関数タイプのサポート:
複数の関数タイプをサポートするには、個別のタイプごとに個別のラッパー関数を作成できます:
func wrap(f func()) func() { return func() { fmt.Println("Before func()") f() fmt.Println("After func()") } } func wrapInt2Int(f func(i int) int) func(i int) int { return func(i int) (ret int) { fmt.Println("Before func(i int) (ret int), i =", i) ret = f(i) fmt.Println("After func(i int) (ret int), ret =", ret) return } }
を使用した汎用ラッパーリフレクション:
Go にはジェネリックスがありませんが、リフレクションを使用したより汎用的なアプローチが可能です。
func wrap(f interface{}) interface{} { switch f2 := f.(type) { case func(i int) (ret int): return func(i int) (ret int) { fmt.Println("Before func(i int) (ret int), i =", i) ret = f2(i) fmt.Println("After func(i int) (ret int), ret =", ret) return } case func(): return func() { fmt.Println("Before func()") f2() fmt.Println("After func()") } } return nil }
ただし、このアプローチではインターフェイス{}の戻り値の型が使用され、次の場合に型アサーションが必要になります。それを使用します。
例使用法:
wf := wrap(myfunc).(func(int) int) ret := wf(2) fmt.Println("Returned:", ret)
出力:
Before, i = 2 myfunc called with 2 After, ret = 4 Returned: 4
以上がGo で関数ラッパーを作成して実行前後にコードを挿入するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。