mcpField
G
golang-naming

golang-naming

github.com/samber开发3.7k41.3k 次安装5 天前更新
代码仓库

关于 golang-naming

面向 Go 开发者和编码 Agent 的命名规范技能,涵盖包、类型、标识符、错误和测试命名。通过规则与示例说明命名方式,并提供重命名和静态检查指引。

主要功能

  1. 01MixedCaps 与缩写大小写规则
  2. 02包、文件和标识符命名规范
  3. 03构造函数、接收者与布尔值命名
  4. 04错误、枚举和测试命名模式
  5. 05命名问题的 Linter 指引

适用场景

  1. 01检查 Go 标识符是否违反规范
  2. 02为新的 Go API 和类型选择名称
  3. 03统一错误和枚举的命名方式
  4. 04规划代码库范围的命名修改

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/samber/cc-skills-golang --skill golang-naming

安装后在 Claude Code 中输入/golang-naming确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

evals/
evals.json
references/
functions-methods.md
identifiers.md
packages-files.md
testing.md
types-errors.md

详细介绍

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

Go 命名约定

Go 偏好简短、易读的名称。大小写决定可见性——大写开头表示已导出,小写开头表示未导出。所有标识符 MUST 使用 MixedCaps,绝 NEVER 使用下划线。

“清晰胜过巧妙。”——Go Proverbs

“设计架构,命名组件,记录细节。”——Go Proverbs

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

快速参考

元素约定示例
包全小写,单个单词;测试文件可以使用 _test 后缀json、http、tabwriter、http_test
文件全小写,可以使用下划线user_handler.go
已导出名称UpperCamelCaseReadAll、HTTPClient
未导出名称lowerCamelCaseparseToken、userCount
接口方法名 + -erReader、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,多类型时用 NewTypeNamering.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 标识符 MUST 使用 MixedCaps(或 mixedCaps)。标识符中绝 NEVER 使用下划线——唯一例外是测试函数子用例(TestFoo_InvalidInput)、生成的代码以及 OS/cgo 互操作。这是关键要求,并非外观问题——Go 的导出机制依赖大小写,工具也默认全面使用 MixedCaps。

// ✓ Good
MaxPacketSize
userCount
parseHTTPResponse

// ✗ Bad — these conventions conflict with Go's export mechanism and tooling expectations
MAX_PACKET_SIZE   // C/Python style
max_packet_size   // snake_case
kMaxBufferSize    // Hungarian notation

避免名称重复

Go 的调用处始终包含包名,因此在标识符中重复包名会浪费读者的时间——http.HTTPClient 会让人不得不解析两次“HTTP”。名称 MUST NOT 重复包名、类型名或周边上下文中已有的信息。

// Good — clean at the call site
http.Client       // not http.HTTPClient
json.Decoder      // not json.JSONDecoder
user.New()        // not user.NewUser()
config.Parse()    // not config.ParseConfig()

// In package sqldb:
type Connection struct{}  // not DBConnection — "db" is already in the package name

// Anti-stutter applies to ALL exported types, not just the primary struct:
// In package dbpool:
type Pool struct{}        // not DBPool
type Status struct{}      // not PoolStatus — callers write dbpool.Status
type Option func(*Pool)   // not 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——如果 0 对应 StatusReady 这样的真实状态,代码就可能表现得像是有人有意选择了该状态,实际上却并非如此。

子测试名称: 在 t.Run() 中,表驱动测试用例名称应为全小写的描述性短语:"valid id"、"empty input"——而不是 "valid ID" 或 "Valid Input"。

详细分类

如需查看完整规则、示例和理由,请参阅:

  • 包、文件与导入别名 — 包命名(单个单词、全小写、不使用复数)、文件命名惯例、导入别名模式(仅在名称冲突时使用,以降低认知负担)以及目录结构。

  • 变量、布尔值、接收者与首字母缩写 — 基于作用域的命名(名称长度应与作用域匹配:3 行循环中用 i,包级变量用更长的名称)、单字母接收者惯例(s 表示 Server)、首字母缩写的大小写(URL 而非 Url,HTTPServer 而非 HttpServer)以及布尔值命名模式(isReady、hasPrefix)。

  • 函数、方法与选项 — getter/setter 模式(Go 省略 Get,因此 user.Name() 读起来自然)、构造函数惯例(New 或 NewTypeName)、命名返回值(仅用于文档说明)、格式化函数后缀(Errorf、Wrapf)以及函数式选项(WithPort、WithLogger)。

  • 类型、常量与错误 — 接口命名(以 -er 结尾的后缀,如 Reader、Closer)、结构体命名(名词、MixedCaps)、常量(MixedCaps,而非 ALL_CAPS)、枚举(使用类型名前缀,如 StatusReady)、哨兵错误(ErrNotFound 变量)、错误类型(以 PathError 作为后缀)以及错误消息惯例(全小写,不加标点)。

  • 测试命名 — 测试函数命名(TestFunctionName)、表驱动测试字段惯例(input、expected)、测试辅助函数命名以及子用例命名模式。

常见错误

错误修正
ALL_CAPS 常量Go 使用大小写表示可见性,而非强调——请使用 MixedCaps(MaxRetries)
GetName() getterGo 省略 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"
从 iota 0 开始的 StatusReady零值应作为哨兵值——在 0 处使用 StatusUnknown,以捕获未初始化的值
"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() 出错时触发 panicMustParse() 会提醒调用者失败时会触发 panic——意外行为应体现在名称中
混用 With*、Set*、Use*保持整个代码库的一致性——With* 是 Go 函数选项的惯例
复数包名Go 的惯例是使用单数(net/url 而非 net/urls)——这样导入路径更一致
Wrapf 没有 f 后缀f 后缀表示格式字符串语义——Wrapf、Errorf 会提示调用者传入格式参数
不必要的导入别名别名会增加认知负担。仅在名称冲突时使用别名——mrand "math/rand"
概念名称不一致同一概念使用 user/account/person 会迫使读者辨别多个同义词——请选用一个名称

应用这些修正意味着要重命名现有标识符——→ 请参阅 samber/cc-skills-golang@golang-gopls 技能,以安全地完成重命名:它会在整个工作区中更新每个调用处,并拒绝会破坏接口满足性的重命名;而 grep/sed 或基于 Edit 的手动重命名会悄然漏掉这类问题。

使用 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 技能
  • → 有关应用命名修复时如何安全重命名,请参阅 samber/cc-skills-golang@golang-gopls 技能
  • → 确定要将标识符重命名为何之后,有关如何大规模安全地应用重命名(gopls Rename/Inline、影响范围映射、分阶段 PR 工作流),请参阅 samber/cc-skills-golang@golang-refactoring 技能

评论

支持 Markdown