Golang 使用 AST 获取方法和参数名以及应用举例

news/2024/5/19 6:19:12 标签: golang, 开发语言, 反射, ast, 模板

背景

在做一些自动生成的代码工作时,有时需要知道方法以及对应的参数名

如果仅是方法,利用反射机制就可以解决

而参数名,程序编译后,已经丢失

可以通过 AST 事先获取方法的参数名

有了方法、参数名,加上反射,那么就可以方便生成胶水代码,自动集成进 HTTP 、 gRPC 等

获取方法、参数名的例子

下面的例子,从特定包 flagInput ,特定的结构体 flagStructName ,获取该结构体所有的方法,以及对应的参数名:

	conf := &packages.Config{
		Mode:       packages.LoadAllSyntax,
		Tests:      false,
	}
	packages, err := packages.Load(conf, flagInput)
	if err != nil {
		fmt.Println("Error loading packages:", err)
		return
	}
	allPackages = packages
	for _, pkg := range packages {
		if pkg.Name != flagPackageName {
			continue
		}
		for _, info := range pkg.TypesInfo.Defs {
			if info == nil {
				continue
			}
			structType, ok := info.Type().(*types.Named)
			if !ok {
				continue
			}
			if structType.Obj().Name() != flagStructName {
				continue
			}

			for i := 0; i < structType.NumMethods(); i++ {
				method := structType.Method(i)
				methodName := method.Name()
				if _, ok := excludeMethods[method.Name()]; ok {
					continue
				}
				sig := method.Type().(*types.Signature)
				params := make([]string, sig.Params().Len())
				for i := 0; i < sig.Params().Len(); i++ {
					params[i] = sig.Params().At(i).Name()
				}
				allMethods[methodName] = params
				sortMethods = append(sortMethods, methodName)
			}

		}
	}

可以把这些信息写入 map 声明,这样代码里就有类似反射参数的功能了。类似:

var methods = map[string][]string{
	"Method1": { "userid", "playerid", "otherparam1", "otherparam2" },
	"Method2": { "userid", "playerid" },
}

集成 HTTP 服务的例子

如有以下类似模板 register.tmpl:

func RegisterMethod(engine *gin.Engine) {
    {{ range .Methods -}}
    engine.Any(HttpPrefix+"{{.}}", func(context *gin.Context) { HandleGin(context, "{{.}}") })
    {{ end -}}
}

通过类似以下代码:

	tmpl, err := template.ParseFiles(flagTmpl)
	if err != nil {
		panic(err)
	}
	var buf bytes.Buffer
	err = tmpl.Execute(&buf, map[string]interface{}{"Methods": sortMethods})
	if err != nil {
		panic(err)
	}

就可以自动生成到 HTTP 的胶水代码:

func RegisterMethod(engine *gin.Engine) {
	engine.Any(HttpPrefix+"Method1", func(context *gin.Context) { HandleGin(context, "Method1") })
	engine.Any(HttpPrefix+"Method2", func(context *gin.Context) { HandleGin(context, "Method2") })
}

例子中的 HandleGin 函数实现,则可以:

  1. 利用方法及对应的参数信息,获取实际参数值
  2. 利用反射,实现对应结构体函数的调用

其他例子

如生成函数的接口调用说明:

模板类似:

{{ range .Methods -}}
{{.Index}}.{{.Comment}} http://api/{{.MethodName}}?{{ range $index, $param := .Params }}{{ if $index }}&{{ end }}{{ $param }}=0{{ end }}
{{ end -}}

还是基于上面的获取的方法、参数名的 map 实例信息,就可以展开了


http://www.niftyadmin.cn/n/5322811.html

相关文章

通信入门系列——微积分中极限、连续、导数、微分、积分

本节目录 一、极限 1、数列极限 2、函数极限 二、连续 三、导数 四、微分 五、积分本节内容 一、极限 1、数列极限 数列极限&#xff1a;设{xn}为一个实数列&#xff0c;A为一个定数。若对任意给定的ε>0&#xff0c;总存在正整数N,使得当n>N时&#xff0c;有|xn-A|<…

八爪鱼拉拉手

欢迎来到程序小院 八爪鱼拉拉手 玩法&#xff1a;点击鼠标左键拖动移动八爪鱼&#xff0c;当他的手很忙的时候他会很高兴&#xff0c; 不同关卡不同的八爪鱼的位置摆放&#xff0c;快去闯关吧^^。开始游戏https://www.ormcc.com/play/gameStart/248 html <div id"gam…

DP读书:《openEuler操作系统》(八)TCP、UDP与跨机器通讯

10min速通TCP与UDP 2024 DP读书计算机网络简介TCP/IP协议栈A. 物理层1.信号及信道传递2.信号调制与调解3.信道的复用 B. 数据链路层1.封装成帧2.透明传输3.差错控制 C. 网络层1.IP2.ARP3.路由选择协议 D. 传输层1.端口号2.3.UDP 2024 DP读书 第八章 跨机器通讯 在第六章之中&a…

【k8s】Kubernetes 声明式 API、命令式

1. 资源管理方式&#xff1a; 1>. 命令式对象管理∶直接使用命令去操作kubernetes资源 kubectl run nginx-pod --imagenginx:1.17.1 --port802>. 命令式对象配置∶通过命令配置和配置文件去操作kubernetes资源 kubectl create/patch -f nginx-pod.yaml3>. 声明式对…

【深度学习目标检测】十五、基于深度学习的口罩检测系统-含GUI和源码(python,yolov8)

YOLOv8是一种物体检测算法&#xff0c;是YOLO系列算法的最新版本。 YOLO&#xff08;You Only Look Once&#xff09;是一种实时物体检测算法&#xff0c;其优势在于快速且准确的检测结果。YOLOv8在之前的版本基础上进行了一系列改进和优化&#xff0c;提高了检测速度和准确性。…

自动驾驶二维激光雷达标定板

自动驾驶是人类智慧的结晶&#xff0c;它融合了多种高科技技术&#xff0c;包括传感器技术、计算机视觉、人工智能等&#xff0c;它让汽车具备了自主感知和决策的能力&#xff0c;可以在复杂多变的道路环境中自如应对。这种技术带给我们的不仅仅是出行的便利&#xff0c;更是对…

代码随想录day29 回溯开始进入排列问题

491.递增子序列 题目 给定一个整型数组, 你的任务是找到所有该数组的递增子序列&#xff0c;递增子序列的长度至少是2。 示例: 输入: [4, 6, 7, 7]输出: [[4, 6], [4, 7], [4, 6, 7], [4, 6, 7, 7], [6, 7], [6, 7, 7], [7,7], [4,7,7]] 思考 这题初看想用子集的方法来做…

Roscpp中构造函数与析构函数及在无人机串口通信应用

1. 概念辨析 构造函数 作用&#xff1a;初始化&#xff0c;在创建对象时会自动调用&#xff0c;有点像Python中的 __init__ 方法 特点&#xff1a;命名为class命名&#xff0c;在public中声明。 析构函数 作用&#xff1a;完成释放前的一些清理工作。 特点&#xff1a;命名…