gofmt是唯一强制格式化工具,必须通过gofmt -w无变更才可提交;包名全小写单词且与目录名一致;导出标识符首字母大写;error必须显式检查并位于返回值末尾。

gofmt 是唯一必须强制执行的格式化工具,其他规范都应围绕它展开,而不是堆砌检查项。
怎么用 gofmt 做最小可行约束
不追求“完美格式”,只守住底线:所有提交的代码必须能通过 gofmt -w 无变更。这意味着:
- 团队不用争论空格/换行/括号位置,
gofmt自动决定 - CI 流水线只需加一行:
git diff --exit-code $(gofmt -l .),有差异就失败 - 编辑器配置只保留两项:
"editor.formatOnSave": true和"go.formatTool": "gofmt",禁用任何自定义格式化插件 - 不启用
-s(简化模式)——它会删空行,反而让逻辑块边界变模糊,对中小团队可读性帮助有限
命名只卡三件事:包名、导出名、错误处理
中小团队最常翻车的是包名冲突和错误被忽略,这两类问题直接导致编译失败或线上 panic,必须硬性约束:
- 包名必须全小写、单单词、与目录名一致,禁止
user_utils、UserModule、user-v1这类写法;user就是user - 所有导出函数/结构体/接口,首字母必须大写;所有非导出项,首字母必须小写——这是 Go 的可见性机制,绕不开
- 任何调用返回
error的函数,if err != nil分支必须显式存在,禁止用_忽略,也不允许只log.Printf而不return - 不强制要求注释风格、缩写规则、变量前缀——这些靠 Code Review 现场对齐更高效
import 怎么管才不增加协作成本
导入混乱在中小型项目里主要体现为循环引用和第三方包随意引入,不是格式问题:
- 禁止在非测试文件中使用
.导入(如import . "net/http"),它会让调用来源不可追溯 - 禁止相对路径导入(如
import "./internal/db"),所有路径必须是模块路径,能被go get解析 - 不强制 import 分组顺序(标准库 / 第三方 / 本地),但要求同一组内按字典序排列——
goimports可自动做到,比手写可靠 - 不禁止
util包,但要求它必须有明确职责(如util/time只处理时间格式转换),且不能被internal外部依赖
为什么不要一开始就上 golint 和 go vet
它们报的很多是“风格建议”,比如 exported func xxx should have comment 或 should omit type string,在中小团队早期会严重拖慢节奏:
立即学习“go语言免费学习笔记(深入)”;
-
golint已被官方标记为 deprecated,revive是更现代的替代,但配置复杂度高 -
go vet的部分检查(如printf参数类型)确实有用,但建议只开启atomic、copylock、nilness这三个真正防 runtime 错误的子检查 - 把
go vet -vettool=vet放进 CI 前,先确保团队 100% 掌握gofmt和命名约束——否则每天都在修“没意义的警告” - 真正的质量瓶颈从来不在格式,而在并发读写 map、goroutine 泄漏、error 忽略——这些靠静态检查不如靠 Code Review + 一次线上事故记得牢
gofmt、包名、导出规则、error 处理这四条,就是中小团队能守住的底线。其余的,等第一个服务上线、第一个线上 bug 归因到某条未约束的实践时,再补不迟。


















