函数类型转换

时间:2014-03-07 15:00:40

标签: generics reflection go

如何将func add (a, b int) int转换为func(...interface{}) interace{}类型?

有关使用reflect包实现通用函数的任何想法吗?

2 个答案:

答案 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),而不是反射库。