
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 實作問題。
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 後綴 | 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 |
| 變體:context | 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() context 變體 |
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技能以了解介面命名深度與接收器設計 - → 請參閱
samber/cc-skills-golang@golang-lint技能以了解自動化強制執行(revive、predeclared、misspell、errname)





