好的變數名稱是程式可讀性的關鍵要素。名稱既不是隨意取的暱稱,也不是越短越好的縮寫——它應該精確地描述變數所代表的實體。本章涵蓋命名的一般原則、特定資料型別的命名、命名慣例、縮寫策略,以及應避免的命名陷阱。
11.1 選擇好名稱的考量#
最重要的原則#
名稱應該完整且精確地描述變數所代表的實體。最好的技巧是用文字說明變數代表什麼,而那句話本身往往就是最佳的名稱。
numberOfPeopleOnTheUsOlympicTeam— 可讀但太長n,np— 太短,毫無意義numTeamMembers,teamMemberCount— 剛剛好
名稱應該傾向描述問題領域(what)而非實作細節(how)。例如用
employeeData而非inputRec,用printerReady而非bitFlag。
最佳名稱長度#
研究顯示,變數名稱平均 10 到 16 個字元時,除錯所需的心力最低。8 到 20 個字元的範圍也不錯。太短的名稱(如 x)無法傳達足夠資訊,太長的名稱則會模糊程式的視覺結構。
作用域對名稱的影響#
- 短名稱(如
i):適合用於作用域極小的區域變數或迴圈變數,暗示該變數沒有超出幾行程式碼的意義。 - 長名稱:適合用於全域變數或不常使用的變數。
- 全域命名空間中的變數應考慮加上子系統前綴(如
g_RunningTotal),或使用namespace/package來避免衝突。
計算值限定詞#
當變數包含計算值(如 Total、Sum、Average、Max、Min)時,將限定詞放在名稱末尾:
revenueTotal,expenseAverage— 一致且對稱- 避免混用
totalRevenue和revenueTotal
Num的歧義:放在開頭(numCustomers)表示總數,放在末尾(customerNum)表示索引。建議改用Count/Total表示總數,Index表示索引,避免混淆。
常見對稱詞組#
命名中使用對稱詞組能提升一致性和可讀性:
begin/end、first/last、min/maxnext/previous、old/new、open/closesource/target、source/destinationvisible/invisible、locked/unlocked、up/down
11.2 為特定型別的資料命名#
迴圈索引(Loop Indexes)#
- 簡單迴圈可使用
i、j、k,但如果迴圈超過幾行或有巢狀結構,應使用有意義的名稱。 - 巢狀迴圈中,
score[teamIndex][eventIndex]遠比score[i][j]清晰,也能避免索引交叉錯誤(index cross-talk)。 - 若變數在迴圈結束後仍會使用,必須給予描述性名稱(如
recordCount)。
狀態變數(Status Variables)#
- 不要用
flag作為名稱——它不傳達任何意義。 - 用具體的描述取代:
dataReady、reportType、recalcNeeded。 - 搭配列舉型別或具名常數來設定和測試值,例如
reportType == ReportType_Annual,而非printFlag == 16。
暫存變數(Temporary Variables)#
temp、x等名稱通常代表程式設計師尚未充分理解問題。- 應替換為有意義的名稱,例如將二次方程式中的
temp改為discriminant。
布林變數(Boolean Variables)#
常見的好名稱包括:
| 名稱 | 語意 |
|---|---|
done | 某件事是否已完成 |
error | 是否發生錯誤 |
found | 是否已找到目標值 |
success / ok | 操作是否成功(可用更具體的名稱如 processingComplete) |
- 布林名稱應暗示 true/false 的語意——
status是差勁的布林名稱,statusOK才好。- 使用正面語意的名稱:
found比notFound好,因為if not notFound難以閱讀。- 有些程式設計師喜歡加上
is前綴(如isDone、isFound),好處是讓模糊的名稱無所遁形(isStatus?顯然不合理)。
列舉型別(Enumerated Types)#
- 為成員加上群組前綴,例如
Color_Red、Color_Blue、Planet_Earth。 - 若語言會自動以型別名稱作為前綴(如
Color.Red),則不需重複。
具名常數(Named Constants)#
- 命名應描述常數代表的抽象實體,而非它的值。
CYCLES_NEEDED是好名稱,FIVE是壞名稱——因為FIVE = 6.0就顯得荒謬了。
11.3 命名慣例的力量#
命名慣例(Naming Conventions)帶來的好處不在於選擇了哪套規則,而在於有規則存在這個事實本身:
- 減少局部決策的負擔,讓注意力集中在更重要的事物上
- 在專案間轉移知識,加速學習新程式碼
- 避免同一概念出現多個名稱(如
pointTotal和totalPoints並存) - 彌補語言本身的弱點(如模擬具名常數或區分變數作用域)
- 強調相關變數之間的關係
適合建立命名慣例的時機:多人協作、程式碼會被維護或審查、專案規模大到無法全部記在腦中、或有大量領域特定術語需要標準化。
11.4 非正式命名慣例#
語言無關的通用指引#
- 變數和物件以小寫字母開頭(
variableName),函式以大寫字母開頭(RoutineName())。 - 區分類別與物件:可透過首字母大小寫、前綴(
t_、a_)、或給物件更具體的名稱(employeeWidget)。 - 全域變數:加
g_前綴。 - 成員變數:加
m_前綴。 - 具名常數:使用
ALL_CAPS。 - 列舉成員:以型別名稱作前綴(
Color_Red)。 - 增強可讀性:使用 camelCase 或 underscore_case 來分隔單字,但不要在同一專案中混用。
各語言的慣例#
點擊展開:各主要語言的命名慣例
C 語言:
c/ch表示字元、i/j表示整數索引、n表示數量、p表示指標、s表示字串- 巨集用
ALL_CAPS,變數和函式用all_lowercase,以底線分隔
C++:
i/j表示整數索引、p表示指標- 常數、typedef、巨集用
ALL_CAPS - 類別用
MixedUpperAndLowerCase,變數和函式用camelCase
Java:
- 常數用
ALL_CAPS,以底線分隔 - 類別和介面用
ClassOrInterfaceName - 變數和方法用
variableOrMethodName - 存取器使用
get/set前綴
11.5 標準化前綴#
標準化前綴(如匈牙利命名法 Hungarian Notation)由兩部分組成:
- 使用者定義型別縮寫(UDT):描述資料型別,如
wn(視窗)、scr(螢幕區域)、doc(文件)、pa(段落)。 - 語意前綴(Semantic Prefix):描述變數的用途,如
c(計數)、i(索引)、first/last(陣列的首尾元素)、min/max(絕對邊界)、g(全域)、m(成員)、p(指標)。
例如:firstPaActiveDocument(活動文件的第一個段落)、cPa(段落數量)、iPa(段落索引)。
標準化前綴的好處是讓名稱更精練且一致,但主要陷阱是程式設計師可能因前綴已夠明確而省略有意義的描述性名稱。
iPa雖明確,但ipaActiveDocument可讀性更好。
11.6 建立具備可讀性的短名稱#
現代語言幾乎沒有變數名稱長度的限制,因此很少需要刻意縮寫。若確有需要,以下是幾種策略:
點擊展開:縮寫策略一覽
- 使用字典中的標準縮寫
- 移除非首位的母音(
computer->cmptr、screen->scrn) - 移除冠詞(and、or、the)
- 使用每個單字的前幾個字母
- 在每個單字的第一、二或三個字母後截斷
- 保留每個單字的首尾字母
- 最多使用三個重要單字
- 移除無用的後綴(-ing、-ed)
- 保留每個音節中最顯著的發音
縮寫的注意事項#
- 不要只省一個字元——打一個字幾乎不費力,但可讀性的損失不值得。
- 保持一致——對同一單字始終使用相同縮寫(如全部用
Num或全部用No,不要混用)。 - 名稱必須能唸出來——用
xPos而非xPstn;通過「電話測試」,即能口述程式碼給他人。 - 避免造成誤讀——
ENDB比BEND好。 - 用同義詞解決碰撞——若
fired和full revenue disbursal都縮寫為frd,可改用dismissed和complete revenue disbursal。 - 在專案層級維護標準縮寫文件——納入版本控制,按完整單字排序,避免重複縮寫。
程式碼被閱讀的次數遠多於被撰寫的次數。縮寫策略應該優先考慮閱讀時的便利性,而非撰寫時的方便。
11.7 應該避免的名稱#
| 應避免的類型 | 說明與範例 |
|---|---|
| 誤導性名稱 | 確保名稱無歧義,例如 FALSE 不應作為 “Fig and Almond Season” 的縮寫 |
| 語意相似的名稱 | 若 input 與 inputValue 可以互換而不影響程式,代表兩者都需重新命名 |
| 外觀相似的名稱 | clientRecs 與 clientReps 只差一個字母,容易混淆。至少要有兩個字母的差異 |
| 發音相似的名稱 | wrap 和 rap 在口頭討論時無法區分 |
| 帶數字的名稱 | file1、file2 幾乎總是可以用更好的方式區分。若數字有意義,考慮使用陣列 |
| 刻意拼錯的名稱 | hilite 還是 hilight?沒人記得住「正確的」錯誤拼法 |
| 僅靠大小寫區分 | frd、FRD、Frd 代表不同變數是合法的,但完全是武斷且令人困惑的 |
| 多種自然語言混用 | 跨國專案應統一使用單一自然語言;英語變體也需統一(color vs colour) |
| 與標準型別或保留字衝突 | - |
| 與變數內容完全無關 | margaret 和 pookie 不應出現在程式碼中 |
| 難以辨認的字元 | 注意 1/l/I、0/O、2/Z、S/5、G/6 等容易混淆的配對 |
要點#
- 好的變數名稱是程式可讀性的關鍵,應盡可能具體,避免通用到可用於多種用途。
- 迴圈索引、狀態變數、布林變數、列舉型別、具名常數等,各有各的命名考量。
- 命名慣例的價值在於有慣例存在本身,它能區分區域、類別與全域資料,區分型別、常數、列舉與變數。
- 現代語言中很少需要縮寫;若必須縮寫,應在專案層級記錄並保持一致。
- 程式碼被閱讀的次數遠多於被撰寫的次數,命名應優先考慮閱讀者的便利。