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