go - 在 Go 中将任意函数作为参数传递
问题描述
我正在尝试扩展我对 Go 函数指针的了解,并且我有一个关于在 Go 中将函数作为参数传递的可能性和不可能的问题。
假设我想编写一个decorator()
可以包装任何现有函数的函数。为简单起见,让我们将其限制为只接受一个参数并只返回一个值的函数。
如果我编写一个接受func(interface{}) interface{}
作为参数的装饰器,只要我传入的函数也接受/返回一个interface{}
类型,它就会隐式工作(请参阅 参考资料funcA
)。
我的问题是——有没有办法将现有的类型函数转换为func(string) string
类型,func(interface{}) interface{}
以便它也可以传递给装饰器函数,而无需将其包装在新的匿名函数中(请参阅 参考资料funcB
)?
package main
import (
"fmt"
)
func decorate(inner func(interface{}) interface{}, args interface{}) interface {} {
fmt.Println("Before inner")
result := inner(args)
fmt.Println("After inner")
return result
}
func funcA(arg interface{}) interface{} {
fmt.Print("Inside A, with arg: ")
fmt.Println(arg)
return "This is A's return value"
}
func funcB(arg string) string {
fmt.Print("Inside B, with arg: ")
fmt.Println(arg)
return "This is B's return value"
}
func main() {
// This one works. Output is:
//
// Before inner
// Inside A, with arg: (This is A's argument)
// After inner
// This is A's return value
//
fmt.Println(decorate(funcA, "(This is A's argument)"))
// This doesn't work. But can it?
//fmt.Println(decorate(funcB, "(This is B's argument)"))
}
解决方案
这是不可能的。原因之一是传递参数的机制因函数而异,使用interface{}
arg 并不意味着“接受任何东西”。例如,一个以结构为参数的函数将接收该结构的每个成员,但一个以 interface{} 包含该结构的函数将接收两个字,一个包含结构的类型,另一个包含指向它。
因此,在不使用泛型的情况下,实现这一点的唯一方法是使用适配器函数。
推荐阅读
- javascript - 从 fetch 中传递 Props
- r - R中两个日期之间的差异
- python - 您可以在 Tableau 中使用 Python 作为数据源吗?
- python - 在 numpy 数组的第三维中,将前三个值乘以第四个值
- python-3.x - 在 Windows 中使用超级账本 Sawtooth 的区块链
- grid - RestAssured:如何使用 Grid 在不同节点上执行 RestAssured 测试用例?
- oracle - ORA-12170: TNS: pycharm 中发生连接超时
- javascript - Snap ScrollMagic 部分擦除
- javascript - 你如何使用 Leafletjs 在非地图图像上显示弹出窗口?
- linux - 没有源编译 maven-compiler-plugin:3.5.1:compile in Linux System