我正在尝试扩展我对 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 并不意味着“接受任何东西”。例如,将结构作为 arg 的函数将接收该结构的每个成员,但是将包含该结构的接口(interface){}作为参数的函数将接收两个单词,一个包含结构的类型,另一个包含指向的指针
因此,在不使用泛型的情况下,实现这一点的唯一方法是使用适配器函数。
https://stackoverflow.com/questions/69759462/