命名规则_(程序设计)

程式設計的中**命名規則**（naming convention）是電腦程式設計的原始碼針對標識符的名稱字串進行定義（即「命名」）而規定的一系列規則。通常是為了提高原始碼的易讀性、易認性、程式效率以及可維護性。命名規則根據各個程式語言的規格、記憶體大小等硬體制約、編輯器以及整合式開發環境的功能等等會有各種制約。

## 制定命名規則的好處

## 挑戰

命名規則的選擇（及其執行的程度）通常是一個有爭議的問題，不同派系的人會覺得自己的觀點最好而其他人則是次等的。 而且，即使採用了已知且定義明確的命名規則，某些組織也可能無法始終如一地遵守這些規則，從而導致不一致和混亂。 如果命名規則在內部不一致、任意、難記，或者以其他方式顯得負擔大於好處，則命名規則會遇到更多的挑戰。

## 易讀性

精細挑選的識別碼可以讓開發者和剖析器更容易理解系統在做什麼，或者如何修改或將原始碼擴充運用到新需求上。 比如這句聲明

在語意上是正確的，但是其目的卻不明顯。而相比較之下，寫成

則提示了原始碼的意圖和含義，至少對了解上下文的人來說更清晰。

## 典型要素

### 識別碼長度

最基本的規則中包括對識別碼長度的規定。在某些情況下，上限是通過提供數值來設定的，而另一些情況下則使用了啟發式的方法或準則。

識別碼長度的規則是有爭議的，適當的長度應視具體情況而定。

要考慮的要點包括：

* 較短的識別碼可能比較好，因為它更容易鍵入。（儘管許多 IDE 和文字編輯器都提供了文字補全功能，這可以緩解這種情況）
* 太短的識別碼（例如 a 和 i）很難使用自動搜尋和替換工具來唯一區分。
* 在某些情況下，最好使用長識別碼，因為短識別碼無法包含足夠的語義資訊。
* 縮寫可能令人困惑，應避免使用，但是太長的正式名稱也會因損害代碼可讀性而不受歡迎。

一些早期的鏈結器將變數名限制為 6 個字元或更少，以減少記憶體使用，這也是早期的程式會限制識別碼長度的原因之一。

### 大小寫和數字

一些命名規則對大小寫和數字的使用加以限制，比如只能用小寫字母，或者只能用大寫字母。有些場合雖然可以保留大小寫，但功能上並不賦予區別。

### 多個單詞組成的識別碼

通常推薦使用「有實際含義的識別碼」。如果單個單詞無法表述清晰則可以使用多個單詞，因此命名規則需要規定多個單詞如何連接。這樣還可以避免與各個程式語言使用的保留字衝突的問題。大多數語言的識別碼不允許空格，而不加空格又會導致難以閱讀，因此需要制定空格的替代方式。

#### 用符號區分

在字母數字的單詞裡使用制定的區分字元進行連接，常用有 連字元 ("-") 、底線 ("\_")，比如兩個單詞的 "`two words`"可寫成"`two-words`"或者"`two_words`"。連字元非常常用，包括 COBOL (1959), Forth (1970) 以及 Lisp (1958)，而在 Unix 命令和包里也很常見。在 CSS 中也是如此。 這種做法沒有一個通稱，有人叫 _lisp-case_ 或者 _COBOL-CASE_ （是為了與 _Pascal case_ 相區別），或者叫 _kebab-case_、_brochette-case_ 等等。 但至少是從 2012 年之後，_kebab-case_ 這個叫法越來越流行。

與此相比，在 FORTRAN/ALGOL 語言的傳統中，特別是 C 語言 和 Pascal 語言 家族，曾使用連接號用於 中綴表示法 的減法運算子，而且也不希望前後加空格，因此就無法用此方法來命名識別碼。而用底線連接小寫字母的方法則在 C 家族（包括 Python）里都很常見，比如 _The C Programming Language_ (1978) 即可見到，通稱為 snake case. 而像 UPPER\_CASE 這樣用底線連接大寫字母的做法則常見於 C 預處理器 里的宏，所以被稱為 MACRO\_CASE；以及 Unix 中的 環境變數，比如 bash 里的 BASH\_VERSION。有時會被幽默地稱作 SCREAMING\_SNAKE\_CASE。

#### 用大小寫區分

另一種做法就是在單詞組合成一個字串的中間使用大寫字母，被稱作駝峰式大小寫 "（camelCase）或者"Pascal case"等等，也就把"`two words`"寫成"`twoWords`"或者"`TwoWords`"。這種方式常見於 Pascal、Java, C# 以及 Visual Basic。而對於首字母縮寫詞的處理方式仍會不一樣。（比如 `XMLHttpRequest` 中的 "XML" 和 "HTTP），有些會用小寫以易於打字和閱讀（比如 `XmlHttpRequest`）而有些會保持大寫以保證準確性（如寫成 `XMLHTTPRequest`）。

## 元資料與混合命名規則

有一些命名規則不僅是特定程式、某個特定專案和問題的規則和需求，還通過軟體架構稱為對其下層的程式語言和跨專案的一個方法論框架。

### 匈牙利命名法

最著名的命名規則包括匈牙利命名法，具體包括「系統匈牙利命名法」和「匈牙利應用命名法」。比如變數 szName 中的字首 "sz" 代表其是一個零結束字串。

## 各種語言的命名規則

### C 和 C++

原則上使用小寫字母。在 C 標準庫里，最常用的做法是使用縮寫名稱，如用於測試是字元是否為字母數字的函式寫成 `isalnum` ，而 C++ 的標準庫了則常用底線作為單詞分隔符（如 `out_of_range`）。而 C 預處理的識別碼則只用大寫字母和底線（因為很多程式語言都用全大寫標示常數），帶兩個底線或者以底線和一個大寫字母打頭的名字都預留給編譯器，因此都不能用（比如 `__reserved` 或者 `_Reserved`）。 雖然這表面上與 stropping 類似，但語意上完全不同，因為底線是識別碼的值的一部分，而不是 stropping 那樣只是表示參照： `__foo` 的值是 `__foo` （被預留），而不是 `foo`（但是在一個不同的命名空間）。

### C#

C# 命名規則基本上遵循微軟的 .NET 語言的規範。 （詳見後續 .NET 章節），但 C# 編譯器並不強制使用命名規則。微軟推薦僅用 `PascalCase` 和 camelCase，後者僅用於方法參數和本地方法變數名（包括本地方法 `const` 值）。一個不適用 PascalCase 的特例，是識別碼開頭的雙字母首字母縮寫詞，這時兩個字母都要大寫，如 `IOStream`，但這不適用於更長的首字母縮寫詞裡，如 `XmlStream`。該規範還推薦 `interface` 的名字要用 `PascalCase` 並在開頭加一個大寫字母 `I`，如 `IEnumerable`。

微軟規範對 filed 命名僅限於 `static`, `public` 和 `protected`，並明確指出如果非靜態、或者有其他可接入層級（比如 `internal` 和 `private`）則不在規範範圍之內。 最常用的做法是所有 filed 都使用 PascalCase ，而只有 `private` （且 `const` 或 `static`），這些例外使用 camelCase 並添加一個底線，如 `_totalCount`。

識別碼可以添加 @ 符號卻不改變含義。也就是說 `factor` 和 `@factor` 均指同一個物件。在規則上，這一字首僅用於當該識別碼是預留關鍵詞（比如 `for` 和 `while`，不加字首就不能當成識別碼），或者是有上下文關鍵詞（比如 `from` 和 `where`，並不嚴格要求有字首，至少不是所有聲明都要求，比如儘管 `dynamic dynamic;` 聲明有效，但這會被看作 `dynamic @dynamic;` 以讓讀者立即知道後者是一個變數名）。

### Java

Java 的命名規則是由多個社群制定的，包括昇陽電腦、網景、AmbySoft 等等。下述採用昇陽電腦制定規則的例子，
比如 "CamelCase"，不用空格直接連起來，每個單詞首字母大寫，比如 "CamelCase".

 
縮寫詞長達三個字母及其以上時用 CamelCase 而不是全大寫（比如 `parseDbmXmlFromIPAddress` 不寫作 `parseDBMXMLFromIPAddress`），這個規則可以適用至兩個字母詞 (如 `parseDbmXmlFromIpAddress`).

 

### JavaScript

JavaScript 的內建庫採用與 Java 同樣的命名規則。資料類型和建造函式使用 upper camel case (RegExp, TypeError, XMLHttpRequest, DOMObject) 而方法使用 lower camel case (getElementById, getElementsByTagNameNS, createCDATASection)。為了保持統一，大部分 JavaScript 開發者都遵循此命名規則。

### .NET

微軟公司 Microsoft .NET 推薦大部分識別碼都用 `UpperCamelCase`（而參數和變數推薦用 lowerCamelCase) 這是所有 .NET 語言的通則， 微軟還推薦無需使用（匈牙利命名法那樣的）字首提示， 而是推薦在後面加上基礎類名，如寫成 `LoginButton` 而不是 `BtnLogin`。

### Objective-C

Objective-C 使用源於 Smalltalk 的代碼方式。通用的變數、函式的頂層條目，包括類、協定都用 UpperCamelCase 並用一個短的全大寫字首標示命名空間，比如 `NSString`, `UIAppDelegate`, `NSApp` 以及 `CGRectMake`。常數可以有小寫字母 k 打頭的字首如 `kCFBooleanTrue`。
即時物件的變數使用帶底線的 lowerCamelCase，如 `_delegate` and `_tableView`。Method 名使用多個 lowerCamelCase 並用冒號區分如 `application:didFinishLaunchingWithOptions:`, `stringWithFormat:` and `isRunning`.

### Perl

Perl 繼承了 C 中的一些規則。本地範圍內的變數和子程式名用小寫字母加底線。包變數採用 title case，聲明的常數全大寫。包的名字採用 camel case 但 pragmata 例外，比如 `strict` 和 `mro` 用小寫。

### PHP

PHP 推薦方式寫在 PSR-1 (PHP Standard Recommendation 1) 和 PSR-12 中。 根據 PSR-1，類的名字要用 PascalCase, 類的常數要用 MACRO\_CASE，而 method 名要用 camelCase。

### Python and Ruby

Python 和 Ruby 都推薦類名使用 `UpperCamelCase`，常數名使用 `CAPITALIZED_WITH_UNDERSCORES`，其他名字用 `lowercase_separated_by_underscores`。

### Swift

Swift 語言的命名規則根據不同發布有所變化。但是隨著 Swift 3.0 的重大更新後，其命名規則規範更為清晰，希望能對所有第三方的 API 命名和聲明規則進行標準化。變數、函式聲明的命名規則還是以 `lowerCamelCase` 為基礎。常數通常使用 enum 類型定義。類和其他類型的聲明採用 `UpperCamelCase`。

## 參見

* Checkstyle
* 命名空間
* 一致的網路裝置命名

 

## 注釋

## 外部連結

* American Name Society（頁面存檔備份，存於網際網路檔案館） – promotes onomastics, the study of names and naming practices, both in the United States and abroad.
* coding-guidelines.com has a pdf（頁面存檔備份，存於網際網路檔案館） that uses linguistics and psychology to attempt a cost/benefit analysis of identifier naming issues