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

如何通过Go语言ast包获取函数参数的类型名称?

获取Go函数参数的类型名称(基于ast包)

你已经成功拿到了参数名称,接下来要获取参数类型名称的关键在于处理field.Type——它是一个ast.Expr接口类型,不同的类型对应不同的AST节点,我们需要通过类型断言来识别并提取类型名称。

我给你写一个实用的辅助函数,能处理常见的类型场景(基本类型、指针类型、包限定类型、数组切片类型等):

import "go/ast"

func getTypeName(expr ast.Expr) string {
	switch t := expr.(type) {
	case *ast.Ident:
		// 基本类型(如int、string)或自定义类型(如MyStruct)
		return t.Name
	case *ast.StarExpr:
		// 指针类型(如*int、*MyStruct),递归获取指向的类型名称
		return "*" + getTypeName(t.X)
	case *ast.SelectorExpr:
		// 包限定类型(如fmt.Stringer、net/http.Request)
		return getTypeName(t.X) + "." + t.Sel.Name
	case *ast.ArrayType:
		// 数组/切片类型(如[]int、[5]string)
		if t.Len != nil {
			// 固定长度数组
			return "[" + getTypeName(t.Len) + "]" + getTypeName(t.Elt)
		}
		// 切片
		return "[]" + getTypeName(t.Elt)
	case *ast.MapType:
		// 映射类型(如map[string]int)
		return "map[" + getTypeName(t.Key) + "]" + getTypeName(t.Value)
	// 可以根据需要扩展更多类型,比如chan、func类型等
	default:
		// 处理其他未覆盖的类型,返回占位符或空字符串
		return "unknown_type"
	}
}

然后你可以把这个函数集成到你的原有代码中,修改后如下:

for _, fun := range findFunc(node) { // ast.FuncDecl
	if fun.Recv != nil {
		for _, field := range fun.Type.Params.List {
			for _, name := range field.Names {
				println(name.Name) // 打印参数名称
				// 获取并打印参数类型名称
				typeName := getTypeName(field.Type)
				println("  Type:", typeName)
			}
		}
	}
}

关键说明:

  • ast.Expr是所有表达式节点的接口,不同类型的类型定义对应不同的实现结构体,比如基本类型是*ast.Ident,指针是*ast.StarExpr,包内类型是*ast.SelectorExpr。
  • 辅助函数通过switch-case的类型断言来匹配不同的节点类型,递归处理嵌套类型(比如指针指向的类型、数组的元素类型)。
  • 如果遇到更复杂的类型(比如通道、函数类型),可以在辅助函数里继续添加对应的case分支来支持。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:39:12