
golang-naming
热门Go(Golang)命名规范——涵盖包、构造函数、结构体、接口、常量、枚举、错误、布尔值、接收器、getter/setter、函数选项、缩写、测试函数和子测试名称。在编写新的 Go 代码、审查或重构、选择命名替代方案(New vs NewTypeName、isConnected vs connected、ErrNotFound vs NotFoundError、StatusReady vs StatusUnknown 在 iota 0 处)、讨论 Go 包名(utils/helpers 反模式)或询问 Go 命名最佳实践时使用此技能。当用户提到 MixedCaps vs snake_case、ALL_CAPS 常量、getter 的 Get 前缀或错误字符串大小写时也会触发。请勿用于不涉及命名决策的通用 Go 实现问题。
Go(Golang)命名规范——涵盖包、构造函数、结构体、接口、常量、枚举、错误、布尔值、接收器、getter/setter、函数选项、缩写、测试函数和子测试名称。在编写新的 Go 代码、审查或重构、选择命名替代方案(New vs NewTypeName、isConnected vs connected、ErrNotFound vs NotFoundError、StatusReady vs StatusUnknown 在 iota 0 处)、讨论 Go 包名(utils/helpers 反模式)或询问 Go 命名最佳实践时使用此技能。当用户提到 MixedCaps vs snake_case、ALL_CAPS 常量、getter 的 Get 前缀或错误字符串大小写时也会触发。请勿用于不涉及命名决策的通用 Go 实现问题。
社区默认。 明确取代
samber/cc-skills-golang@golang-naming技能的公司技能优先。
Go 命名规范
Go 偏好简短、可读的名称。大小写控制可见性——大写表示导出,小写表示未导出。所有标识符必须使用 MixedCaps,绝不使用下划线。
"清晰胜于巧妙。" — Go 谚语
"设计架构,命名组件,记录细节。" — Go 谚语
若要忽略某条规则,只需在代码中添加注释。
快速参考
| 元素 | 规范 | 示例 |
|---|---|---|
| 包 | 小写,单个单词,测试文件可用 _test 后缀 | json、http、tabwriter、http_test |
| 文件 | 小写,允许下划线 | user_handler.go |
| 导出名称 | UpperCamelCase | ReadAll、HTTPClient |
| 未导出 | lowerCamelCase | parseToken、userCount |
| 接口 | 方法名 + -er |
Reader、Closer、Stringer |
| 结构体 | MixedCaps 名词 | Request、FileHeader |
| 常量 | MixedCaps(不是 ALL_CAPS) | MaxRetries、defaultTimeout |
| 接收器 | 1-2 字母缩写 | func (s *Server)、func (b *Buffer) |
| 错误变量 | Err 前缀 |
ErrNotFound、ErrTimeout |
| 错误类型 | Error 后缀 |
PathError、SyntaxError |
| 构造函数 | New(单一类型)或 NewTypeName(多类型) |
ring.New、http.NewRequest |
| 布尔字段 | 字段和方法使用 is、has、can 前缀 |
isReady、IsConnected() |
| 测试函数 | Test + 函数名 |
TestParseToken |
| 缩写 | 全大写或全小写 | URL、HTTPServer、xmlParser |
| 变体:上下文 | WithContext 后缀 |
FetchWithContext、QueryContext |
| 变体:原地操作 | In 后缀 |
SortIn()、ReverseIn() |
| 变体:错误 | Must 前缀 |
MustParse()、MustLoadConfig() |
| 选项函数 | With + 字段名 |
WithPort()、WithLogger() |
| 枚举(iota) | 类型名前缀,零值为未知 | StatusUnknown 在 0,StatusReady |
| 命名返回值 | 描述性,仅用于文档 | (n int, err error) |
| 错误字符串 | 小写(包括缩写),无标点 | "image: unknown format"、"invalid id" |
| 导入别名 | 简短,仅在冲突时使用 | mrand "math/rand"、pb "app/proto" |
| 格式化函数 | f 后缀 |
Errorf、Wrapf、Logf |
| 测试表字段 | got/expected 前缀 |
input string、expected int |
MixedCaps
所有 Go 标识符必须使用 MixedCaps(或 mixedCaps)。绝不在标识符中使用下划线——唯一的例外是测试函数子用例(TestFoo_InvalidInput)、生成的代码以及 OS/cgo 互操作。这是关键性的,而非装饰性的——Go 的导出机制依赖于大小写,工具链也期望全程使用 MixedCaps。
// ✓ 好
MaxPacketSize
userCount
parseHTTPResponse
// ✗ 差——这些规范与 Go 的导出机制和工具链期望冲突
MAX_PACKET_SIZE // C/Python 风格
max_packet_size // snake_case
kMaxBufferSize // 匈牙利命名法
避免重复
Go 调用点始终包含包名,因此在标识符中重复它会浪费读者的时间——http.HTTPClient 迫使解析两次 "HTTP"。名称不得重复包名、类型名或周围上下文中已有的信息。
// 好——调用点清晰
http.Client // 不是 http.HTTPClient
json.Decoder // 不是 json.JSONDecoder
user.New() // 不是 user.NewUser()
config.Parse() // 不是 config.ParseConfig()
// 在包 sqldb 中:
type Connection struct{} // 不是 DBConnection——"db" 已在包名中
// 反重复适用于所有导出类型,而不仅仅是主要结构体:
// 在包 dbpool 中:
type Pool struct{} // 不是 DBPool
type Status struct{} // 不是 PoolStatus——调用者写 dbpool.Status
type Option func(*Pool) // 不是 PoolOption
常被忽略的规范
这些规范正确但不明显——它们是最常见的命名错误来源:
构造函数命名: 当包导出单一主要类型时,构造函数是 New(),而不是 NewTypeName()。这避免了重复——调用者写 apiclient.New() 而不是 apiclient.NewClient()。仅当包有多个可构造类型(如 http.NewRequest、http.NewServeMux)时使用 NewTypeName()。
布尔结构体字段: 未导出的布尔字段必须使用 is/has/can 前缀——isConnected、hasPermission,而不是裸的 connected 或 permission。导出的 getter 保留前缀:IsConnected() bool。这读起来自然像一个问题,并将布尔值与其他类型区分开。
错误字符串全小写——包括缩写。 写 "invalid message id" 而不是 "invalid message ID",因为错误字符串通常与其他上下文拼接(fmt.Errorf("parsing token: %w", err)),混合大小写在中句中看起来不对。哨兵错误应包含包名作为前缀:errors.New("apiclient: not found")。
枚举零值: 始终在 iota 位置 0 放置一个显式的 Unknown/Invalid 哨兵。var s Status 静默变为 0——如果它映射到像 StatusReady 这样的真实状态,代码可能表现得好像状态被有意选择,而实际上并未选择。
子测试名称: 表驱动测试用例名称在 t.Run() 中应为全小写描述性短语:"valid id"、"empty input"——而不是 "valid ID" 或 "Valid Input"。
详细分类
完整规则、示例和理由,请参阅:
-
包、文件和导入别名 — 包命名(单个单词、小写、无复数)、文件命名规范、导入别名模式(仅在冲突时使用以减少认知负荷)和目录结构。
-
变量、布尔值、接收器和缩写 — 基于作用域的命名(长度匹配作用域:3 行循环用
i,包级别用更长名称)、单字母接收器规范(Server 用s)、缩写大小写(URL 不是 Url,HTTPServer 不是 HttpServer)和布尔命名模式(isReady、hasPrefix)。 -
函数、方法和选项 — Getter/setter 模式(Go 省略
Get,因此user.Name()读起来自然)、构造函数规范(New或NewTypeName)、命名返回值(仅用于文档)、格式化函数后缀(Errorf、Wrapf)和函数选项(WithPort、WithLogger)。 -
类型、常量和错误 — 接口命名(
Reader、Closer后缀-er)、结构体命名(名词、MixedCaps)、常量(MixedCaps,不是 ALL_CAPS)、枚举(类型名前缀如StatusReady)、哨兵错误(ErrNotFound变量)、错误类型(PathError后缀)和错误消息规范(小写、无标点)。 -
测试命名 — 测试函数命名(
TestFunctionName)、表驱动测试字段规范(input、expected)、测试辅助函数命名和子用例命名模式。
常见错误
| 错误 | 修复 |
|---|---|
ALL_CAPS 常量 |
Go 保留大小写用于可见性,而非强调——使用 MixedCaps(MaxRetries) |
GetName() getter |
Go 省略 Get,因为 user.Name() 在调用点读起来自然。但布尔谓词保留 Is/Has/Can 前缀:IsHealthy() bool 而不是 Healthy() bool |
Url、Http、Json 缩写 |
混合大小写的缩写会产生歧义(HttpsUrl——是 Https+Url 吗?)。使用全大写或全小写 |
this 或 self 接收器 |
Go 方法调用频繁——使用 1-2 字母缩写(Server 用 s)以减少视觉噪音 |
util、helper 包 |
这些名称未说明内容——使用描述抽象的具体名称 |
http.HTTPClient 重复 |
包名始终出现在调用点——http.Client 避免读取两次 "HTTP" |
user.NewUser() 构造函数 |
单一主要类型使用 New()——user.New() 避免重复类型名 |
connected bool 字段 |
裸形容词有歧义——使用 isConnected,使字段读起来像真/假问题 |
"invalid message ID" 错误 |
错误字符串必须全小写,包括缩写——"invalid message id" |
StatusReady 在 iota 0 |
零值应为哨兵——StatusUnknown 在 0 捕获未初始化的值 |
"not found" 错误字符串 |
哨兵错误应包含包名——"mypackage: not found" 标识来源 |
userSlice 类型名中包含实现 |
类型编码实现细节——users 描述它包含什么,而非如何实现 |
| 接收器名称不一致 | 在同一类型的不同方法间切换名称会混淆读者——一致使用一个名称 |
snake_case 标识符 |
下划线与 Go 的 MixedCaps 规范和工具链期望冲突——使用 mixedCaps |
| 短作用域的长名称 | 名称长度应与作用域匹配——3 行循环用 i 即可,userIndex 是噪音 |
| 按值命名常量 | 值会变,角色不变——DefaultPort 在端口更改后仍有效,Port8080 则无效 |
FetchCtx() 上下文变体 |
WithContext 是标准 Go 后缀——FetchWithContext() 立即可识别 |
sort() 原地操作但无 In |
读者假设函数返回新值。SortIn() 表示修改 |
parse() 在错误时 panic |
MustParse() 警告调用者失败会 panic——意外应体现在名称中 |
混用 With*、Set*、Use* |
代码库中保持一致——With* 是 Go 函数选项的规范 |
| 复数包名 | Go 规范是单数(net/url 不是 net/urls)——保持导入路径一致 |
Wrapf 没有 f 后缀 |
f 后缀表示格式字符串语义——Wrapf、Errorf 告诉调用者传递格式参数 |
| 不必要的导入别名 | 别名增加认知负荷。仅在冲突时使用别名——mrand "math/rand" |
| 概念名称不一致 | 对同一概念使用 user/account/person 迫使读者跟踪同义词——选择一个名称 |
使用 Linter 强制执行
许多命名规范问题可由 linter 自动捕获:revive、predeclared、misspell、errname。有关配置和使用,请参阅 samber/cc-skills-golang@golang-lint 技能。
交叉引用
- → 有关更广泛的格式化和风格决策,请参阅
samber/cc-skills-golang@golang-code-style技能 - → 有关接口命名深度和接收器设计,请参阅
samber/cc-skills-golang@golang-structs-interfaces技能 - → 有关自动强制执行(revive、predeclared、misspell、errname),请参阅
samber/cc-skills-golang@golang-lint技能





