golang-naming

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 实现问题。

2261Star
150Fork
更新于 2026/6/6
SKILL.md
只读
名称
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 实现问题。

社区默认。 明确取代 samber/cc-skills-golang@golang-naming 技能的公司技能优先。

Go 命名规范

Go 偏好简短、可读的名称。大小写控制可见性——大写表示导出,小写表示未导出。所有标识符必须使用 MixedCaps,绝不使用下划线。

"清晰胜于巧妙。" — Go 谚语

"设计架构,命名组件,记录细节。" — Go 谚语

若要忽略某条规则,只需在代码中添加注释。

快速参考

元素 规范 示例
小写,单个单词,测试文件可用 _test 后缀 jsonhttptabwriterhttp_test
文件 小写,允许下划线 user_handler.go
导出名称 UpperCamelCase ReadAllHTTPClient
未导出 lowerCamelCase parseTokenuserCount
接口 方法名 + -er ReaderCloserStringer
结构体 MixedCaps 名词 RequestFileHeader
常量 MixedCaps(不是 ALL_CAPS) MaxRetriesdefaultTimeout
接收器 1-2 字母缩写 func (s *Server)func (b *Buffer)
错误变量 Err 前缀 ErrNotFoundErrTimeout
错误类型 Error 后缀 PathErrorSyntaxError
构造函数 New(单一类型)或 NewTypeName(多类型) ring.Newhttp.NewRequest
布尔字段 字段和方法使用 ishascan 前缀 isReadyIsConnected()
测试函数 Test + 函数名 TestParseToken
缩写 全大写或全小写 URLHTTPServerxmlParser
变体:上下文 WithContext 后缀 FetchWithContextQueryContext
变体:原地操作 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 后缀 ErrorfWrapfLogf
测试表字段 got/expected 前缀 input stringexpected 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.NewRequesthttp.NewServeMux)时使用 NewTypeName()

布尔结构体字段: 未导出的布尔字段必须使用 is/has/can 前缀——isConnectedhasPermission,而不是裸的 connectedpermission。导出的 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() 读起来自然)、构造函数规范(NewNewTypeName)、命名返回值(仅用于文档)、格式化函数后缀(ErrorfWrapf)和函数选项(WithPortWithLogger)。

  • 类型、常量和错误 — 接口命名(ReaderCloser 后缀 -er)、结构体命名(名词、MixedCaps)、常量(MixedCaps,不是 ALL_CAPS)、枚举(类型名前缀如 StatusReady)、哨兵错误(ErrNotFound 变量)、错误类型(PathError 后缀)和错误消息规范(小写、无标点)。

  • 测试命名 — 测试函数命名(TestFunctionName)、表驱动测试字段规范(inputexpected)、测试辅助函数命名和子用例命名模式。

常见错误

错误 修复
ALL_CAPS 常量 Go 保留大小写用于可见性,而非强调——使用 MixedCapsMaxRetries
GetName() getter Go 省略 Get,因为 user.Name() 在调用点读起来自然。但布尔谓词保留 Is/Has/Can 前缀:IsHealthy() bool 而不是 Healthy() bool
UrlHttpJson 缩写 混合大小写的缩写会产生歧义(HttpsUrl——是 Https+Url 吗?)。使用全大写或全小写
thisself 接收器 Go 方法调用频繁——使用 1-2 字母缩写(Server 用 s)以减少视觉噪音
utilhelper 这些名称未说明内容——使用描述抽象的具体名称
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 后缀表示格式字符串语义——WrapfErrorf 告诉调用者传递格式参数
不必要的导入别名 别名增加认知负荷。仅在冲突时使用别名——mrand "math/rand"
概念名称不一致 对同一概念使用 user/account/person 迫使读者跟踪同义词——选择一个名称

使用 Linter 强制执行

许多命名规范问题可由 linter 自动捕获:revivepredeclaredmisspellerrname。有关配置和使用,请参阅 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 技能