Go中可通过reflect包获取函数类型信息:用reflect.TypeOf(f).In(i)和.Out(i)遍历参数与返回值,t.IsVariadic()识别变参,t.Elem()获取变参元素类型,命名返回名不可见但类型准确。

在 Go 中,可以通过 reflect 包获取函数的类型信息,包括参数个数、类型、是否为变参,以及返回值个数和类型。核心是使用 reflect.TypeOf(func).In(i) 和 reflect.TypeOf(func).Out(i)。
获取函数类型并确认是否为函数
反射操作前必须确保传入的是函数值(而非函数调用结果),且需用 reflect.TypeOf 获取其类型。Go 的函数类型属于 reflect.Func 种类,可通过 Kind() 验证:
- 传入函数变量(如
myFunc),不能传myFunc() -
reflect.TypeOf(f).Kind() == reflect.Func是安全判断 - 若传入 nil 函数,
reflect.TypeOf(nil)返回nil,需提前判空
遍历参数类型(支持普通参数与变参)
使用 t.In(i) 获取第 i 个参数类型(i 从 0 开始),参数总数由 t.NumIn() 返回。变参会被表示为切片类型,但可通过 t.IsVariadic() 单独识别:
-
t.NumIn()返回所有参数个数(含变参占位符) -
t.IsVariadic()为true表示最后一个参数是变参 - 若为变参,
t.In(t.NumIn()-1)返回类似[]int的切片类型 - 可调用
paramType.Elem()获取变参元素类型(如[]string→string)
获取返回值类型(含命名返回与错误惯用法)
返回值通过 t.Out(i) 获取,总数由 t.NumOut() 给出。Go 不在类型系统中保留返回值名称,因此反射无法得知命名返回名,但能准确反映类型结构:
立即学习“go语言免费学习笔记(深入)”;
- 常见多返回场景(如
func() (int, error))会返回两个类型:int和error - 若函数有命名返回(如
func() (x int, e error)),反射结果完全一致,无额外信息 - 可结合
rt.String()或rt.Kind()判断是否为reflect.Interface类型(如error)
实用示例:打印函数签名
以下代码可打印任意函数的完整签名(参数 + 返回值):
func PrintFuncSignature(f interface{}) {t := reflect.TypeOf(f)
if t.Kind() != reflect.Func {
log.Fatal("not a function")
}
var params []string
for i := 0; i pt := t.In(i)
if i == t.NumIn()-1 && t.IsVariadic() {
params = append(params, "..."+pt.Elem().String())
} else {
params = append(params, pt.String())
}
}
var results []string
for i := 0; i results = append(results, t.Out(i).String())
}
fmt.Printf("func(%s) %s\n", strings.Join(params, ", "), strings.Join(results, ", "))
}










