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 }
但是,此方法使用 interface{} 返回类型,并且在以下情况下需要类型断言:使用它。
示例用法:
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中文网其他相关文章!