在go中发现当前函数的返回类型



我有一个使用反射和反射生成的函数。MakeFunc,所以直到运行时我才有返回类型。

在MakeFunc使用的模板函数中,是否有一种方法来确定被模板化的具体函数的返回类型?

本质上,是否有一种方法可以在运行时确定当前执行函数的返回类型?

我知道Out方法:

fn.Type().Out(0)

我可以很容易地找到一个函数的返回类型吗?

但是是否有一种方法可以找到当前正在执行的函数的返回类型(而不是显式传递的函数引用)?

您应该检查fn.Type().Out(0).Kind(),例如:

func main() {    
    fnTmpl := func(in []reflect.Value) []reflect.Value {
        return []reflect.Value{in[0]}
    }
    makeFn := func(fptr interface{}) {
        fn := reflect.ValueOf(fptr).Elem()
        fn.Set(reflect.MakeFunc(fn.Type(), fnTmpl))
    }
    var nFn func(int) int
    makeFn(&nFn)
    kind := reflect.TypeOf(nFn).Out(0).Kind()
    switch kind {
    case reflect.Int:
        fmt.Println("int")
    }
}

在这种情况下,当前执行的函数的返回类型总是[]reflect。类型(因为这是函数传递给反映的内容)。MakeFunc必须返回)。您真正需要的是反射的返回类型。makeFuncStub函数调用你的函数。

没有办法得到这个(除非对调用堆栈进行一些奇怪的检查),但是您可以创建一个增强版本的MakeFunc,它提供以下信息:

package main
import (
    "fmt"
    "reflect"
)
// MakeFunc is like reflect.MakeFunc, but fn has an extra argument, retType, which
// is passed the desired return type.
func MakeFunc(typ reflect.Type, fn func(args []reflect.Value, retType reflect.Type) (results []reflect.Value)) reflect.Value {
    if n := typ.NumOut(); n != 1 {
        panic("wrong number of return values")
    }
    rt := typ.Out(0)
    return reflect.MakeFunc(typ, func(args []reflect.Value) (results []reflect.Value) {
        return fn(args, rt)
    })
}
func makeReturnOne(fptr interface{}) {
    fn := reflect.ValueOf(fptr).Elem()
    fn.Set(MakeFunc(fn.Type(), returnOne))
}
func returnOne(args []reflect.Value, retType reflect.Type) []reflect.Value {
    ret := reflect.New(retType).Elem()
    switch retType.Kind() {
    case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
        ret.SetInt(1)
    case reflect.Float32, reflect.Float64:
        ret.SetFloat(1.0)
    default:
        panic("returnOne only supports int and float types")
    }
    r := ret.Interface()
    fmt.Printf("returning %v as %Tn", r, r)
    return []reflect.Value{ret}
}
func main() {
    var r1f func() float64
    var r1i func() int
    makeReturnOne(&r1f)
    makeReturnOne(&r1i)
    fmt.Println(r1f())
    fmt.Println(r1i())
}

我可能误解了你想要实现的目标,但为什么不直接接受你要返回的值呢?修改OneOfOne示例如下:

fnTmpl := func(in []reflect.Value) (res []reflect.Value) {
    res = []reflect.Value{in[0]}
    fmt.Println("Returned:", res[0].Kind())
    return res
}

游乐场:http://play.golang.org/p/EujmxyGRrI

相关内容

  • 没有找到相关文章

最新更新