You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言中如何完整获取函数签名的参数与返回值类型信息

问题描述

我编写了一个用于返回函数签名字符串表示的函数:

func getFuncSignature(v interface{}) string {

    funcValue := reflect.ValueOf(v)
    funcType := funcValue.Type()
    name := funcType.Name()

    // Function signature
    var params []string
    for i := 0; i < funcType.NumIn(); i++ {
        nm := funcType.In(i).Name()
        if strings.TrimSpace(nm) == "" {
            nm = "<unk>"    // <<<<<<<<<<<<<<<<<<<<<<<< HERE 1
        }
        params = append(params, nm)
    }

    var returns []string
    for i := 0; i < funcType.NumOut(); i++ {
        nm := funcType.Out(i).Name()
        if strings.TrimSpace(nm) == "" {
            nm = "<unk>"  // <<<<<<<<<<<<<<<<<<<<<<<<<< HERE 2
        }
        returns = append(returns, nm)
    }

    paramsStr := strings.Join(params, ", ")
    returnsStr := strings.Join(returns, ", ")

    if name != "" {
        return fmt.Sprintf("(func %s(%s) => (%s))", name, paramsStr, returnsStr)
    }

    return fmt.Sprintf("(func(%s) => (%s))", paramsStr, returnsStr)
}

但部分参数和返回值的类型名称会返回空字符串,只能用<unk>替代,这并不理想。请问是否有方法可以获取输入和返回值的名称/类型?

解决方法

问题出在你使用的Type.Name()方法——它仅返回自定义命名类型的名称,对于内置类型(如int、string)、匿名类型、指针/切片/映射这类复合类型,都会返回空字符串。

要获取完整的类型描述,应该改用Type.String()方法,它会返回类型的完整字符串表示:

  • 内置类型int返回"int"
  • 指针类型*int返回"*int"
  • 自定义结构体type User struct{}返回"main.User"(包含包名)
  • 切片[]string返回"[]string"

修改后的代码如下:

func getFuncSignature(v interface{}) string {
    funcType := reflect.TypeOf(v)
    name := funcType.Name()

    var params []string
    for i := 0; i < funcType.NumIn(); i++ {
        params = append(params, funcType.In(i).String())
    }

    var returns []string
    for i := 0; i < funcType.NumOut(); i++ {
        returns = append(returns, funcType.Out(i).String())
    }

    paramsStr := strings.Join(params, ", ")
    returnsStr := strings.Join(returns, ", ")

    if name != "" {
        return fmt.Sprintf("(func %s(%s) => (%s))", name, paramsStr, returnsStr)
    }

    return fmt.Sprintf("(func(%s) => (%s))", paramsStr, returnsStr)
}

额外补充两点:

  • 如果想去掉类型中的包名(比如把main.User简化为User),可以做判断:当Type.Name()不为空时用Name(),否则用String()
  • 函数的Name()返回空是正常情况(比如匿名函数、闭包),这部分可以保留原逻辑

内容的提问来源于stack exchange,提问作者Alexander Mills

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 11:27:37