2022-11-13:以下go语言代码中,如何获取结构体列表以及结构体内的指针方法列表?以下代码应该返回{“S1“:[“M1“,“M2“],“S2“:[],“S3“:[“M1“,“M3“]},顺序不限
2022-11-13:以下go语言代码中,如何获取结构体列表以及结构体内的指针方法列表?以下代码应该返回{“S1”:[“M1”,“M2”],“S2”:[],“S3”:[“M1”,“M3”]},顺序不限。S1的M3方法不是指针方法,S3的M2方法也不是指针方法,所以不能输出。
package main
type S1 struct{}
func (this *S1) M1() {}
func (this *S1) M2() {}
func (this S1) M3() {}
type S2 struct{}
type S3 struct{}
func (this *S3) M1() {}
func (this S3) M2() {}
func (this *S3) M3() {}
答案2022-11-14:
这道题有人说用反射,实际上反射是无法解决这个问题的,原因是无法直接使用结构体。
要解析rust的代码,go/ast、go/parser、go/token,要用到这三个包。
使用场景是写框架。
代码用go语言编写。代码如下:
package main
import (
"encoding/json"
"fmt"
"go/ast"
"go/parser"
"go/token"
)
const content = `package main
type S1 struct{}
func (this *S1) M1() {}
func (this *S1) M2() {}
func (this S1) M3() {}
type S2 struct{}
type S3 struct{}
func (this *S3) M1() {}
func (this S3) M2() {}
func (this *S3) M3() {}`
func main() {
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, "", content, parser.ParseComments)
if err != nil {
fmt.Println(err)
return
}
structInfoList := make([]*StructInfo, 0)
structInfoMap := make(map[string]*StructInfo)
// 找结构体
for i := 0; i < len(f.Decls); i++ {
decl, ok := f.Decls[i].(*ast.GenDecl)
if !ok {
continue
}
if decl.Tok != token.TYPE {
continue
}
if len(decl.Specs) != 1 {
continue
}
spec, ok2 := decl.Specs[0].(*ast.TypeSpec)
if !ok2 {
continue
}
structType, ok3 := spec.Type.(*ast.StructType)
if !ok3 {
fmt.Println("失败", structType)
continue
}
structInfo := NewStructInfo(spec.Name.Name)
structInfoList = append(structInfoList, structInfo)
structInfoMap[spec.Name.Name] = structInfo
}
// 找方法
for i := 0; i < len(f.Decls); i++ {
decl, ok := f.Decls[i].(*ast.FuncDecl)
if !ok {
continue
}
if decl.Recv == nil || len(decl.Recv.List) != 1 {
continue
}
structName := ""
switch decl.Recv.List[0].Type.(type) {
case *ast.StarExpr: //指针方法
structName = decl.Recv.List[0].Type.(*ast.StarExpr).X.(*ast.Ident).Name
case *ast.Ident: //普通方法
//structName = decl.Recv.List[0].Type.(*ast.Ident).Name
}
if structInfo, ok := structInfoMap[structName]; ok {
structInfo.MethodNameList = append(structInfo.MethodNameList, decl.Name.Name)
}
}
// 输出
data, _ := json.MarshalIndent(structInfoList, "", " ")
fmt.Println(string(data))
}
type StructInfo struct {
StructName string `json:"structName,omitempty"`
MethodNameList []string `json:"methodNameList,omitempty"`
}
func NewStructInfo(structName string) *StructInfo {
return &StructInfo{StructName: structName, MethodNameList: make([]string, 0)}
}
执行结果如下:

2022-11-13:以下go语言代码中,如何获取结构体列表以及结构体内的指针方法列表?以下代码应该返回{“S1“:[“M1“,“M2“],“S2“:[],“S3“:[“M1“,“M3“]},顺序不限的更多相关文章
- 客户端的javascript改变了asp.net webform页面控件的值,后台代码中如何获取修改后的值。
客户端的javascript改变了asp.net webform页面控件的值,后台代码中如何获取修改后的值. 无论是什么的html控件,只要加上了runat="server" ...
- 读陈浩的《C语言结构体里的成员数组和指针》总结,零长度数组
原文链接:C语言结构体里的成员数组和指针 复制例如以下: 单看这文章的标题,你可能会认为好像没什么意思.你先别下这个结论,相信这篇文章会对你理解C语言有帮助.这篇文章产生的背景是在微博上,看到@Lar ...
- C语言的结构体和C++结构体的区别
关于C++中声明结构体中需要使用构造器创建实例对象的语法: <C++的结构体构造方法的基本概念:结构体的构造方法需要和结构体的名字相同,并且无返回值,也不要void关键字,这样的方法就是构造器的 ...
- C语言的结构体和 C++结构体的区别
C语言的结构体和 C++结构体的区别 关于C++中声明结构体中需要使用构造器创建实例对象的语法: <C++的结构体构造方法的基本概念:结构体的构造方法需要和结构体的名字相同,并且无返回值,也不 ...
- GO学习-(38) Go语言结构体转map[string]interface{}的若干方法
结构体转map[string]interface{}的若干方法 本文介绍了Go语言中将结构体转成map[string]interface{}时你需要了解的"坑",也有你需要知道的若 ...
- VS编程,WPF中,获取鼠标相对于当前屏幕坐标的一种方法
原文:VS编程,WPF中,获取鼠标相对于当前屏幕坐标的一种方法 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/det ...
- java静态代码块/静态属性、构造块、构造方法执行、main方法、普通代码块的顺序
java静态代码块/静态属性.构造块.构造方法执行.main方法.普通代码块的顺序 这也是在笔试中的一个重要的考点,就有一个输出语句让你写出输出的结果. 理论知识: 静态代码块是:属于类的,在类加载时 ...
- MFC中的NMHDR结构体和NMUPDOWN结构体
建立spin控件,创建UDN_DELTAPOS一个消息函数后: void CSpinDlg::OnDeltaposSpin1(NMHDR* pNMHDR, LRESULT* pResult) { NM ...
- C++结构体与Delphi结构体相互传参,结构体中包含结构体的嵌套,数组指针
//结构体的声明 typedef struct Mwinddirectbaseline { char* p; int s; int i; }Mwinddirectbaseline; typedef s ...
- C语言 结构体(嵌套结构体--结构体数组)
//结构体--嵌套结构体和结构体数组 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> ...
随机推荐
- lnmp重新安装mysql
安装mysql好长时间,一直没去管,后来一直频繁重启,各种网上找方案去解决,最后问题太异常,一顿操作猛如虎之后把mysql彻底搞垮,无奈只能进行重装. whereis mysql mysql: /us ...
- (转)codeblocks 使用研究
原帖:http://github.tiankonguse.com/blog/2014/10/11/codeblocks-shutcut.html 使用前 使用 codeblocks 前肯定是下载安装 ...
- AttributeError: module 'torch._six' has no attribute 'PY3'
修改:进到torch._six源码,看看里面是PY的哪个对象,修改成这对象名试试 _six.py 即将PY3修改为PY37
- ElasticSearch 实现分词全文检索 - term、terms查询
数据准备 ElasticSearch 实现分词全文检索 - 测试数据准备 ElasticSearch的各种查询 不会对查询关键字进行分词 term 查询 term的查询是代表完全匹配,搜索之前不会对你 ...
- Spring--AOP通知类型
AOP通知类型 前置通知 通知类中的数据在原始数据的前面 后置通知 通知类中的数据在原始数据的后面 环绕通知 若是只是加一个注解: 我们需要这样做:加一个参数: 若是面对有返回值的方法,又有一点不同之 ...
- Java数据脱敏(手机号|邮箱号|身份证号|银行卡号)
参考博客:https://blog.csdn.net/ywb201314/article/details/107762279
- Windows命令行备份文件
windows命令行备份文件 0 前言 前段时间,笔者因为在C盘爆满的情况下被windows自动更新了(大概),出现了以下情况: 在试了几种方法后不起作用,无奈下只能重装系统. 在这之前要把之前的一些 ...
- 最新 umi4-max 如何使用 webpack5 联邦模块
新项目用 umi4-max 搭建,部分功能想要使用其他项目的功能,不想重新开发,想到了使用 webpack5 的联邦模块,可以直接引用其他项目代码来实现共享代码. 理想很美好,现实很残酷.直接按照 w ...
- MyBatisPlus--入门
入门案例 MyBatisPlus(MP)是基于MyBatis框架基础上开发的增强型工具,旨在简化开发.提高效率. 1.新建springboot项目(版本2.5.0),仅保留JDBC 添加mybatis ...
- Linux 多服务器时间同步设置
找一个机器,作为时间服务器,所有的机器与这台集群时间进行定时的同步,比如,每隔十分钟,同步一次时间. 一.配置时间服务器具体步骤