go vet 是生产级检查器,专揪“能编译但危险”的误用,如类型不匹配、循环变量闭包、未导出字段加 json tag 等,不教语法基础;staticcheck 更适合学习,提示 defer 位置错误、零值冗余判断等易懂问题。

go vet 不是学习辅助工具,而是生产级检查器;想靠它学 Go 语法或规范,会走偏。 它只报“符合语法但大概率错”的问题,不教基础语法规则,也不解释为什么该用 fmt.Printf 而不是 fmt.Println——它只告诉你“fmt.Println 里用了 %s,这不对”。
go vet 不检查语法错误,只揪“能编译但危险”的写法
它不介入语言学习过程,而是过滤掉那些编译器放行、但运行时出问题的典型误用。比如:
-
fmt.Printf("%d", "hello")—— 类型错,go vet报Printf format %d has arg ... of wrong type string -
for _, v := range items { ptrs = append(ptrs, &v) }—— 所有指针都指向最后一个v,go vet触发loopclosure检查器 -
type User struct { name string `json:"name"` }—— 字段未导出却加jsontag,序列化永远为空,go vet直接标出
这些不是初学者该死记硬背的规则,而是写熟 Go 后容易踩的“惯性坑”。你得先知道 struct 字段首字母小写=不可导出,go vet 才会提醒你 tag 白写了。
真正适合边学边用的静态工具是 staticcheck
staticcheck 比 go vet 更贴近学习场景,它会指出:
-
if err != nil { return } defer f.Close()——defer在return后不会执行,staticcheck标为SA1021 -
var x int; if x == 0 { ... }—— 未初始化变量默认零值,staticcheck提示SA1019(虽常被忽略,但对理解零值机制有提示作用) for i := 0; i —— 推荐改用 <code>range,staticcheck给出SA4001
它的警告带编号和文档链接(如 https://staticcheck.io/docs/checks#SA1021),点开就能看到原理、反例、正例——这才是边写边学的节奏。安装只需:go install honnef.co/go/tools/cmd/staticcheck@latest,然后跑 staticcheck ./。
golint 已归档,别再用它学规范
官方早在 2021 年就归档了 golint,它不再维护,且规则老旧(比如强制首字母大写注释、禁止下划线命名)。现在社区通用的是 staticcheck 的风格检查子集,或直接用 golangci-lint 配置 stylecheck 等现代 linter。
- 想统一命名风格?
staticcheck的ST1000(导出名需大驼峰)、ST1005(错误消息不应大写首字母)更合理 - 想检查注释缺失?
staticcheck的SA1019和SA1027能覆盖导出项文档要求 - 运行
staticcheck -checks=ST1000,ST1005 ./就能聚焦风格问题,不干扰逻辑检查
硬套过时的 golint 规则,反而会让你写出“合规但奇怪”的 Go 代码。
CI 里怎么配才不误导新人
在 GitHub Actions 或 GitLab CI 中,别把 go vet 和 staticcheck 当成“作业批改器”来用。它们不是教学反馈,而是质量门禁:
-
go vet ./必须失败即中断:任何输出都代表真实风险,不能 warn-only -
staticcheck ./建议分两层:核心检查(-checks=SA,ST)设为失败,风格类(ST1005)可 warn-only 或禁用 - 绝对不要加
-fix自动修复——staticcheck不提供安全自动修,go vet更不支持
新人第一次 PR 被 go vet 拒绝,最该给的不是“按提示改”,而是“看这个链接,搞懂为什么 range 取地址会出事”。工具只是钩子,背后的理解不能跳过。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











