golang-naming

golang-naming

熱門

Go (Golang) 命名慣例 — 涵蓋套件、建構函式、結構體、介面、常數、列舉、錯誤、布林值、接收器、getter/setter、函式選項、縮寫、測試函式與子測試名稱。當你撰寫新的 Go 程式碼、進行程式碼審查或重構、在命名替代方案之間做選擇(例如 New 與 NewTypeName、isConnected 與 connected、ErrNotFound 與 NotFoundError、StatusReady 與 StatusUnknown 在 iota 0 的位置)、討論 Go 套件名稱(utils/helpers 反模式)、或詢問 Go 命名最佳實務時,請使用此技能。當使用者提到 MixedCaps 與 snake_case、ALL_CAPS 常數、getter 的 Get 前綴、或錯誤字串的大小寫時,也請觸發此技能。請勿用於不涉及命名決策的一般 Go 實作問題。

2261星標
150分支
更新於 2026/6/6
SKILL.md
readonlyread-only
name
golang-naming
description

Go (Golang) 命名慣例 — 涵蓋套件、建構函式、結構體、介面、常數、列舉、錯誤、布林值、接收器、getter/setter、函式選項、縮寫、測試函式與子測試名稱。當你撰寫新的 Go 程式碼、進行程式碼審查或重構、在命名替代方案之間做選擇(例如 New 與 NewTypeName、isConnected 與 connected、ErrNotFound 與 NotFoundError、StatusReady 與 StatusUnknown 在 iota 0 的位置)、討論 Go 套件名稱(utils/helpers 反模式)、或詢問 Go 命名最佳實務時,請使用此技能。當使用者提到 MixedCaps 與 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
變體:context 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() context 變體 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 技能以了解介面命名深度與接收器設計
  • → 請參閱 samber/cc-skills-golang@golang-lint 技能以了解自動化強制執行(revive、predeclared、misspell、errname)