Reflection 查找go中当前函数的返回类型

Reflection 查找go中当前函数的返回类型,reflection,go,Reflection,Go,我有一个使用reflection和reflect.MakeFunc生成的函数,所以在运行时之前我实际上没有返回类型 在MakeFunc正在使用的模板函数中,是否有方法确定正在模板化的具体函数的返回类型 从本质上讲,是否有一种方法可以在运行时确定当前正在执行的函数的返回类型iof 我知道Out方法: fn.Type().Out(0) 我能很容易地找到函数的返回类型吗 但是有没有办法找到当前正在执行的函数的返回类型(与显式传递的函数引用相反) 您应该检查fn.Type().Out(0.Kind()

我有一个使用reflection和reflect.MakeFunc生成的函数,所以在运行时之前我实际上没有返回类型

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

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

我知道Out方法:

fn.Type().Out(0)
我能很容易地找到函数的返回类型吗


但是有没有办法找到当前正在执行的函数的返回类型(与显式传递的函数引用相反)

您应该检查
fn.Type().Out(0.Kind()
,了解:


我可能误解了你们想要实现的目标,但为什么不接受你们所回报的价值呢?将One的示例修改如下:

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

操场:

在您所说的情况下,当前执行函数的返回类型始终为[]reflect.type(因为传递给reflect.MakeFunc的函数必须返回该类型)。您真正想要的是调用您的函数的reflect.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 %T\n", 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())
}

我本质上希望找到fnTmpl的具体实现的返回类型。在本例中,nFn返回一个int。在fnTmpl内部,我如何确定返回类型是int?这没有任何意义,请给出一个示例,说明您期望得到什么和实际得到什么。在您的示例中,当您调用nFn(I)时,实际上正在执行并传递包装值的是fnTmpl。在fnTmpl内部,我如何确定nFn类型应该返回int?我认为这是不可能的,但也许其他人会有更好的主意。是的,这也是我目前的印象:)在上面的示例中,Kind()正在对输入参数进行操作。如果我的输入和输出是由包装器函数的类型决定的,那么在函数实现执行之前,我不知道它的类型。
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 %T\n", 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())
}