問題ステートメント:
関数を受け入れ、その変更されたバージョンを返す関数ラッパーを探します。このラッパーは、元の関数呼び出しの前後の両方でカスタム コードの実行を挿入することを目的としています。
解決策:
Go では、関数リテラルを利用することでこれを実現できます。特定の関数シグネチャを指定すると、同じシグネチャを持つ関数を受け取り、返すラッパー関数を作成できます。ラッパー関数には、必要なカスタム動作が組み込まれています。
例を考えてみましょう:
func myfunc(i int) int { fmt.Println("myfunc called with", i) return i * 2 }
関数の変更と拡張:
次のラッパー関数はログ記録を追加します。元の呼び出しの前後のステートメントmyfunc:
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) // Invokes the provided function fmt.Println("After, ret =", ret) return } }
使用法とデモ:
説明するために、ラップされた関数が変数に割り当てられ、実行:
wf := wrap(myfunc) ret := wf(2) fmt.Println("Returned:", ret)
出力:
Before, i = 2 myfunc called with 2 After, ret = 4 Returned: 4
複数の関数タイプへの拡張:
この概念は、サポートするように拡張できます。個別の型ごとに個別のラッパー関数を作成することにより、さまざまなパラメーターと戻り値の型で関数をラップします。たとえば、パラメーターや戻り値の型を持たない関数をラップする場合:
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 で関数ラッパーを作成して関数の実行前後にコードを挿入するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。