Generic 使用反射检查分配给接口{}变量的函数的签名

Generic 使用反射检查分配给接口{}变量的函数的签名,generic,currying,reflection,go,Generic,Currying,Reflection,Go,我正在尝试构建一个如下所示的函数: package curry import ( "fmt" "reflect" ) // Function type fn interface{} // Function parameter type pr interface{} // It return the curried function func It(f fn, p ...pr) (fn, error) { // examine the concret type of

我正在尝试构建一个如下所示的函数:

package curry

import (
    "fmt"
    "reflect"
)

// Function
type fn interface{}

// Function parameter
type pr interface{}

// It return the curried function
func It(f fn, p ...pr) (fn, error) {
    // examine the concret type of the function f
    if reflect.ValueOf(f).Kind() == reflect.Func {
    // Get the slice of input and output parameters type 
    } else {
        return nil, fmt.Errorf("%s", "takes a function as a first parameter")
    }
    // _, _ = f, p
    return nil, nil
}

是否可以将输入和输出参数类型的切片提取为函数
f
[]reflect.Type

您可以使用
reflect.Type.In(int)
reflect.Type.Out(int)
,有相应的方法称为
NumIn()int
NumOut()int
提供输入/输出的数量

但是,请记住一些注意事项:

  • 要正确地提取任意签名的函数,需要无限多个案例。您必须依次切换每个输入和输出以正确获取要提取的类型
  • 无论如何,您都不能动态创建函数。SliceOf、MapOf等没有FuncOf方法。无论如何,您都必须手工编写咖喱版本
  • 使用反射来模拟泛型通常被认为是一个坏主意™.
    如果你一定要做这样的事情,我强烈建议你制作一个接口,让每个实现自己动手,而不是试图“一般”地对所有情况进行破解,这在Go 1.2.1中永远不会起作用。

    你可以使用
    reflect.Type.In(int)
    reflect.Type.Out(int)
    ,有相应的方法称为
    NumIn()int
    NumOut()int
    ,它们为您提供输入/输出的数量

    但是,请记住一些注意事项:

  • 要正确地提取任意签名的函数,需要无限多个案例。您必须依次切换每个输入和输出以正确获取要提取的类型
  • 无论如何,您都不能动态创建函数。SliceOf、MapOf等没有FuncOf方法。无论如何,您都必须手工编写咖喱版本
  • 使用反射来模拟泛型通常被认为是一个坏主意™.
    如果你一定要做这样的事情,我强烈建议你制作一个接口,让每个实现自己动手,而不是试图“一般”地对所有情况进行破解,这在Go 1.2.1中永远不会起作用。

    Go 1.5将添加一个功能,在这里可能会有所帮助。 (,by)

    测试用例包括以下有趣的代码:

    v := MakeFunc(FuncOf([]Type{TypeOf(K(""))}, []Type{TypeOf(V(0))}, false), fn)
    outs := v.Call([]Value{ValueOf(K("gopher"))})
    

    Go 1.5将在此处添加一个有帮助的函数。 (,by)

    测试用例包括以下有趣的代码:

    v := MakeFunc(FuncOf([]Type{TypeOf(K(""))}, []Type{TypeOf(V(0))}, false), fn)
    outs := v.Call([]Value{ValueOf(K("gopher"))})