Go代码规范核心是降低协作成本,gofmt强制统一格式,包名全小写、导出标识符首字母大写,接口命名仅单方法时用er后缀,error必须显式检查且位于返回值末尾。

Go 代码不是“写完能跑就行”,而是“别人一眼看懂、工具自动维护、改起来不踩坑”。官方规范本质是降低协作成本,不是设门槛。
gofmt 是强制标准,不是可选项
所有 Go 代码必须经 gofmt -w 处理后再提交。它不只是调格式,还决定括号位置、空格有无、换行时机——这些细节人工无法长期一致。
-
gofmt用 Tab 缩进(非空格),VS Code 等编辑器需确认设置为 “Insert spaces” 关闭、“Tab size” 设为 4,否则保存时可能混入空格 - 别手动对齐字段或参数:结构体字段垂直对齐、函数参数按列排开,都是反模式;
gofmt会把它打乱成单列,这是故意的 - 行宽建议 ≤120 字符,但
gofmt不强制换行;过长表达式应拆成中间变量,而非靠格式硬撑
包名和导出标识符大小写决定可见性
Go 没有 public/private 关键字,全靠首字母大小写控制作用域。这不是风格偏好,是语言机制。
- 包名必须全小写,如
http、sql、grpc;util或common这类包名会被 lint 工具警告,因语义太模糊 - 导出标识符(函数、类型、常量)必须首字母大写:
ParseJSON、UserID、MaxRetries - 非导出标识符(包内私有)必须首字母小写:
parseJSON、userID、maxRetries - 特有名词缩写要统一:如
HTTPClient(不是HttpClient)、APIKey(不是ApiKey),参考go/lint内置的 initialism 列表
接口命名以 er 结尾,但只适用于单方法接口
不是所有接口都叫 XXXer。这个约定只在接口只含一个方法时成立,且该方法名去掉 er 后恰好匹配。
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
立即学习“go语言免费学习笔记(深入)”;
- 正确:
Reader→ 方法Read;Writer→ 方法Write;Closer→ 方法Close - 错误:
UserService(含Create、Update、Delete多个方法)——应叫UserRepository或UserStore,不带er - 接口定义越小越好:
io.Reader只管读,io.ReadCloser是组合,不要一上来就定义ReadWriterCloser - 方法名本身不加
er:func (u *User) IsAdmin() bool正确;IsAdminer是错的
error 必须显式检查,且永远是最后一个返回值
Go 的错误不是异常,不抛不捕。忽略 err 是最常见也最危险的 bug 来源。
- 函数签名必须把
error放最后:func ReadFile(name string) ([]byte, error),不能倒过来 - 检查必须紧随调用之后:
data, err := os.ReadFile("x"); if err != nil { ... };不能先处理data再检查err - 不要用
_忽略错误,除非你明确知道这个调用不可能失败(极少见);defer file.Close()后仍要检查err - 包装错误用
fmt.Errorf("xxx: %w", err),保留原始调用栈;用%v或%s会丢失链路
真正难的不是记住规则,而是在写业务逻辑时下意识绕过“我想这么写”的惯性——比如给结构体字段加注释、把长条件拆成变量、让接口只有一件事。这些不是装饰,是防止半年后自己看不懂的最低成本防护。

















