Go-Slang 并不存在,它是对 Go 官方 ast 解析生态的误解;所有静态分析均基于 go/parser、go/ast 和 go/token 标准库组合,第三方工具也依赖此体系。

Go-Slang 并不存在 —— 这是个常见误解,Golang 官方生态里没有叫 Go-Slang 的 AST 解析库。所有基于 go/ast 的静态分析都依赖 go/parser + go/ast + go/token 这套标准库组合,第三方工具(如 gofumpt、staticcheck)也全跑在这之上。
为什么搜“Go-Slang”找不到包或文档
它不是 Go 官方库,也不是知名社区项目(比如没在 pkg.go.dev 或 GitHub trending 里出现过)。你可能混淆了以下几种情况:
- 把
go/ast误记成go-slang(拼写近似) - 看到某篇博客用错名,把自定义 parser 命名为 “slang” 后误传为库名
- 和其它语言的 slang 工具(如 Ruby 的
parsergem、Rust 的syn)记混了
真正可用的 AST 解析入口只有 parser.ParseFile 和 parser.ParseExpr,别无替代。
parser.ParseFile 调用前必须检查的四件事
90% 的 panic 都源于这四点没校验:
立即学习“go语言免费学习笔记(深入)”;
-
fset必须是token.NewFileSet()创建的非 nil 值,否则所有node.Pos()返回0,定位失效 - 文件名参数可传空字符串
"",但若走磁盘加载,建议传绝对路径;若走内存解析(src != nil),它只是占位符,不校验存在性 -
mode不能为0:要注释就加parser.ParseComments,要容忍语法错误继续解析就加parser.AllErrors -
src决定读取方式:传nil表示从文件路径加载;传字符串(如os.ReadFile结果)则必须非 nil,否则解析器直接跳过
典型崩溃:panic: interface conversion: ast.Node is nil, not *ast.FuncDecl,基本等于你没检查 err != nil 就直接访问了 file。
ast.Inspect 回调里安全提取函数信息的写法
别写 f.Name.Name 前不判空,也别对 f.Type.Params.List 直接 range —— Params 和 Results 都可能是 nil,不是空切片:
- 函数名在
f.Name.Name,不是f.Name(后者是*ast.Ident节点,未判空取.Name会 panic) - 参数列表要先判
f.Type.Params != nil,再遍历.List;匿名参数(如func(int))的field.Names是空切片,取[0]必崩 -
f.Doc仅当mode含parser.ParseComments才非 nil;f.Comments是整个文件的注释列表,不是函数专属 - 闭包字面量是
*ast.FuncLit,Name恒为nil,别和*ast.FuncDecl混用类型断言
想解析非 Go 代码?go/parser 不行,得另起炉灶
go/parser 只认合法 Go 语法。你要解析 DSL、配置表达式或自定义规则语言,它直接报错或返回 nil:
-
strconv和json.Unmarshal只做类型转换,不生成 AST - 手写 lexer + parser 最可控,但得自己处理运算符优先级、错误提示和 token 位置映射
- 第三方方案如
peg(PEG parser generator)可声明式定义语法规则,生成 Go 代码,适合中等复杂度 DSL - 所有自定义 AST 都得自己定义结构体,
go/ast的节点类型(如*ast.CallExpr)不可替换、不可扩展
真正容易被忽略的点是:AST 本身不带类型信息 —— go/ast 只管语法,go/types 才负责语义。想查变量真实类型、跨包引用或接口实现,必须上 go/types,光靠 AST 不够。


















