2022-11-13:以下go语言代码中,如何获取结构体列表以及结构体内的指针方法列表?以下代码应该返回{"S1":["M1",
2023-06-13 09:16:48 时间
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)}
}
执行结果如下:
相关文章
- Go 编程 | 连载 02 - 变量与常量
- Go 编程 | 连载 11 - 复杂数据类型 Slice
- Go栈内存管理
- go富集分析和kegg富集分析的区别_非模式生物怎么做GO富集
- 《Go语言精进之路:从新手到高手的编程思想、方法和技巧1》4-6章笔记
- Go 编程 | 连载 27 - 正则表达式
- 如何优雅的通过Shell脚本一键部署GO项目到服务器 |Go主题月
- 【Go】留意 Select 的预求值!
- 开篇:为什么学习 Go 语言
- Go语言中常见100问题-#6 Interface on the producer side
- 「Go工具箱」go语言csrf库的使用方式和实现原理
- Go-标准库-log(一)
- Go-包管理-go get(二)
- Go-包管理-go build(一)
- Go-包管理-go install
- Go基础之–结构体和方法详解编程语言
- Go语言圣经-指针对象的方法-bit数组习题详解编程语言
- 编程新精英:Go语言 Redis开发(go语言redis开发)
- Go语言连接Oracle数据库实战(go连接oracle)
- 如何在Linux上安装Go语言?——简单易懂的指南(linux安装go语言)
- MySQL中使用Go语言的好处(mysql中go什么)
- Go语言查询Oracle数据库实战实例(go语言查询oracle)