如何将func add (a, b int) int
转换为func(...interface{}) interace{}
类型?
有关使用reflect包实现通用函数的任何想法吗?
答案 0 :(得分:1)
正如JimB所说,你不能在Go中进行转换而你不能像这样转换函数但是通过使用闭包,你可以快速包装你的函数:
func add(a, b int) int {
return a + b;
}
wrap := func(args ...interface{}) interface{} {
return interface{} (add(args[0].(int), args[1].(int)))
}
请注意,如果您为其赋予非int类型的参数,则wrap会发生混乱。如果你想避免它,你可以稍微修改wrap:
wrap := func(args ...interface{}) (interface{}, error) {
a, k := args[0].(int)
b, l := args[1].(int)
if !k || !l {
return nil, errors.New("Arguments must be of type int")
}
return add(a,b), nil
}
如果你想用wrap做不同的事情,根据它的参数类型你可以通过使用类型开关来实现:
func addInts(a, b int) int {
return a + b;
}
func addFloat64s(a, b float64) float64 {
return a + b;
}
wrap := func(args ...interface{}) interface{} {
switch args[0].(type) {
case int: return interface{}(addInts(args[0].(int), args[1].(int)))
case float64: return interface{}(addFloat64s(args[0].(float64), args[1].(float64)))
}
}
请注意,最后一个版本的包装假设所有给定的参数都具有相同的类型,并且至少给出了2个参数。
答案 1 :(得分:0)
没有“铸造”去(好吧,使用“不安全”的包类似于铸造)。
你不能像这样转换函数类型,因为它们在内存中有不同的布局。类似通用的函数可以通过反射包进行,但具有很大的开销。有关示例,请参阅http://golang.org/pkg/reflect/#example_MakeFunc。
对于大多数泛型函数的用例,你最好接受一个接口,并使用类型断言或开关(http://golang.org/ref/spec#Type_switches),而不是反射库。