直接用ast.inspect配合类型断言可覆盖90%静态分析需求,但必须防nil、带fset、设对mode,否则易panic或结果为空;parser.parsefile前须检查fset非nil、文件名合理、src与mode正确设置。

直接用 ast.Inspect 配合类型断言就能覆盖 90% 的静态分析需求,但必须防 nil、带 fset、设对 mode,否则一跑就 panic 或结果为空。
parser.ParseFile 调用前必须检查的四件事
几乎所有崩溃都源于上下文没配齐:
-
fset必须是token.NewFileSet()创建的非nil值,否则所有node.Pos()返回 0,定位失效 - 第二个参数(文件名)传空字符串
""可以,但若走磁盘读取,建议传绝对路径;若走内存解析(src非nil),它只是占位符,不校验存在性 - 第四个参数
mode不能为nil:要注释就加parser.ParseComments,要容忍语法错误继续解析就加parser.AllErrors -
src决定读取方式:传nil表示从文件路径加载;传字符串(如os.ReadFile结果)则必须非nil,否则解析器直接跳过
遍历 *ast.FuncDecl 时为什么拿不到函数名或参数
*ast.FuncDecl 字段命名和语义脱节,直接取容易 panic:
- 函数名在
f.Name.Name,不是f.Name——后者是*ast.Ident节点,未判空就取会崩 -
f.Type.Params和f.Type.Results可能为nil(比如func hello() {}),不是空切片,必须先判空再访问.List - 参数是
*ast.Field,名字在field.Names([]*ast.Ident),匿名参数(如func(int))该切片为空,取[0]必 panic -
f.Doc是函数上方的注释,但仅当mode包含parser.ParseComments才非nil;f.Comments是整个文件注释列表,不是函数专属
ast.Inspect 回调里怎么安全提取信息
它比手写递归稳,但用法有硬约束:
- 回调签名是
func(node ast.Node) bool,返回false表示“别往下走了”,适合找第一个main - 别在回调里对
node做指针比较(比如node == someNode),AST 节点没实现==,会恒为false - 如果需要上下文(比如当前在哪个函数里),自己维护栈结构,
Inspect不提供作用域信息 - 注意:它不能改 AST —— 所有节点都是只读副本,改了也没用。真要重写代码,得用
golang.org/x/tools/go/ast/astutil或手动生成新节点 - 最常被忽略的是:即使
err == nil,f.Decls也可能为nil(尤其解析空文件或含严重语法错误时),而ast.Inspect对nil节点不做防护,直接 panic
真正难的不是写对第一行 ast.Inspect,而是每次访问 Params、Results、Names、Doc 前都条件反射地敲出 != nil 判断——这个习惯漏一次,panic 就在下一行等着。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











