函数类型转换

huangapple go评论83阅读模式
英文:

Functions type converting

问题

你好!以下是你要翻译的内容:

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

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

英文:

How can I convert func add (a, b int) int to func(...interface{}) interace{} type ?

Any ideas about implementing generic functions using the reflect package ?

答案1

得分: 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)))
}

注意,如果给wrap函数传递的参数不是int类型,wrap函数会引发panic错误。如果你想避免这种情况,可以稍微修改wrap函数:

wrap := func(args ...interface{}) (interface{}, error) {
    a, k := args[0].(int)
    b, l := args[1].(int)
    if !k || !l {
        return nil, errors.New("参数必须是int类型")
    }
    return add(a, b), nil
}

如果你想根据wrap函数的参数类型执行不同的操作,可以使用类型切换(type switch):

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)))
    }
}

注意,上述最后一个版本的wrap函数假设所有给定的参数都具有相同的类型,并且至少给出了两个参数。

英文:

As JimB said, you can't cast in Go and you cannot convert functions just like that but by using closures, you can rapidly wrap your function:

func add(a, b int) int {
    return a + b;
}

wrap := func(args ...interface{}) interface{} {
    return interface{} (add(args[0].(int), args[1].(int)))
}

Note that wrap will panic if you give it arguments that are not of type int. If you want to avoid that you can slightly modify 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
}

If you'd like to do different things with wrap, depending on it's arguments types you can do so by using a type switch:

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)))
    }
}

Note that this last version of wrap makes the assumption that all given parameters will have the same type and at least 2 arguments are given.

答案2

得分: 0

在Go语言中,没有像"casting"这样的操作(尽管使用"unsafe"包有点像casting)。

你不能像这样转换函数类型,因为它们在内存中的布局是不同的。可以通过reflect包创建类似泛型的函数,但会带来显著的开销。可以参考http://golang.org/pkg/reflect/#example_MakeFunc中的示例。

对于大多数使用泛型函数的情况,最好接受一个接口,并使用类型断言或类型切换(http://golang.org/ref/spec#Type_switches),而不是使用反射库。

英文:

There is no "casting" is go (well, using the "unsafe" package kind of is like casting).

You cannot convert function types like this, since they have different layouts in memory. Generic-like functions can be made through the reflect package, though with significant overhead. See http://golang.org/pkg/reflect/#example_MakeFunc for an example.

For most use cases of generic functions, you're probably better off accepting an interface, and using type assertions or switches (http://golang.org/ref/spec#Type_switches), rather than the reflection library.

huangapple
  • 本文由 发表于 2014年3月7日 23:00:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/22253539.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定