代碼風格

一套用于编写计算机程序源代码的规则或准则

代碼風格(英語:Programming style)即程式開發人員所編寫原始碼的書寫風格。良好的代碼風格會幫助程式設計師閱讀和理解符合該風格的原始碼,並且避免錯誤。

關於該主題的經典著作是 1970 年代編寫的《編程風格的要素》英語The Elements of Programming Style,並以當時流行的 FortranPL/I 語言的範例進行了說明。

特定程式中使用的編程風格可能源自公司或其他計算組織的代碼約定英語Coding conventions,以及代碼作者的偏好。編程風格通常是為特定的程式語言(或語言家族)設計的:在 C 原始碼中被認為是良好的風格可能不適合 BASIC 原始碼等等。但是,一些規則通常適用於許多語言。

良好風格的要素

總結程式設計實踐中的經驗,代碼風格的要素包括(但不限於)以下幾點:

代碼外觀

代碼風格通常處理原始碼的可視外觀,帶有可讀性的目標。軟體很長時間都可以格式化原始碼,讓寫代碼的人將注意力集中在命名,邏輯和更進階的技術。作為一個實際的點,用電腦來格式化原始碼節省了時間,且使不帶網路論戰地實施全公司的標準成為可能。

縮排

縮排風格協助確認控制流和代碼塊。在一些程式語言中,縮排被用來限定代碼的邏輯塊;在這些情況下正確的縮排不僅僅是風格的事。在其他語言中,縮排和空白字元不影響功能,雖然有邏輯和一貫的縮排是代碼更易於閱讀。比較:

if (hours < 24 && minutes < 60 && seconds < 60) {
    return true;
} else {
    return false;
}

if (hours < 24 && minutes < 60 && seconds < 60)
{
    return true;
}
else
{
    return false;
}

和像是這樣

if  ( hours   < 24
   && minutes < 60
   && seconds < 60
)
{return    true
;}         else
{return   false
;}

前兩個範例很可能更容易閱讀,因為它們以既定的方式縮排("hanging paragraph" 樣式)。這種縮排風格在處理多個巢狀結構時特別有用。

ModuLiq

ModuLiq Zero 縮排風格用Enter分組而不是縮排。和所有以上的比較:

if (hours < 24 && minutes < 60 && seconds < 60)
return true;

else
return false;

Lua

Lua不用傳統的花括號括號。if/else 語句只需要表達式後面有then,以end結束 if/else 語句。

if hours < 24 and minutes < 60 and seconds < 60 then
  return true
else
  return false
end

縮排是可選的。and,or,not在 true/false 語句間被使用。

它們是真/假陳述,如

print(not true)

會代表假。

Python

Python 用縮排來表明控制結構,所以正確的縮排是需要的。通過這麼做,用花括號(亦即{})包括的需要就被清除。另一方面,複製和貼上 Python 代碼可能導致問題,因為被貼上的代碼的縮排級別可能和當前行的縮排級別不同。這樣的重格式化用手做可能十分乏味,但一些文字編輯器整合式開發環境有自動做的功能。也有當 Python 代碼被發表在去除空白字元的論壇或網頁上,使它變得無法使用的問題,雖然這個問題可以在能用保留空白字元的標籤,像"<pre> ... </pre>"(HTML中),"[code]"..."[/code]"(bbcode英語bbcode中)等等時避免。

if hours < 24 and minutes < 60 and seconds < 60:
    return True
else:
    return False

注意 Python 不適用花括號,而是一個普通的英文冒號(例子else:)。

許多 Python 程式設計師傾向於遵循一種公認的風格指南,稱為 PEP8。[1]有一些工具旨在自動化 PEP8 合規性。

Haskell

Haskell 類似地有越位規則,也就是它有一種二維語法,在其中縮排對定義塊有意義(雖然另一種語法用花括號和分號)。Haskell 是一種聲明式語言,在 Haskell 指令碼中有語句,但是有聲明。範例:

let c_1 = 1
    c_2 = 2
in
    f x y = c_1 * x + c_2 * y

可以被寫成一行,如:

let {c_1=1;c_2=2} in f x y = c_1 * x + c_2 * y

Haskell 鼓勵 文學編程 的使用,擴充的文字解釋代碼的緣由。在文學式 Haskell 指令碼(帶有副檔名lhs)中,所有東西都是注釋,除了標記為代碼的塊。程式可以用 LaTeX 編寫,這種情況下 code 環境標記哪裡是代碼。並且每個活動的代碼段落可以被在前面和後面帶上空行的方式標記,以一個大於號和一個空格開始每一行代碼。這裡有一個使用 LaTeX 標記的:

The function \verb+isValidDate+ test if date is valid
\begin{code}
isValidDate :: Date -> Bool
isValidDate date = hh>=0  && mm>=0 && ss>=0
                 && hh<24 && mm<60 && ss<60
 where (hh,mm,ss) = fromDate date
\end{code}
observe that in this case the overloaded function is \verb+fromDate :: Date -> (Int,Int,Int)+.

一個使用純文字的例子:

The function isValidDate test if date is valid

> isValidDate :: Date -> Bool
> isValidDate date = hh>=0  && mm>=0 && ss>=0
>                  && hh<24 && mm<60 && ss<60
>  where (hh,mm,ss) = fromDate date

observe that in this case the overloaded function is fromDate :: Date -> (Int,Int,Int).

垂直對齊

將相似的元素垂直對齊經常是有幫助的,使錯字導致的錯誤更加明顯。比較:

$search = array('a', 'b', 'c', 'd', 'e');
$replacement = array('foo', 'bar', 'baz', 'quux');

// Another example:

$value = 0;
$anothervalue = 1;
$yetanothervalue = 2;

$search      = array('a',   'b',   'c',   'd',   'e');
$replacement = array('foo', 'bar', 'baz', 'quux');

// Another example:

$value           = 0;
$anothervalue    = 1;
$yetanothervalue = 2;

空格

在一些需要空白字元的情況下,絕大部分自由形式語言的語法不關心出現了多少空白字元。與空白字元相關的風格被普遍用來加強可讀性。目前沒有已知的確鑿事實(研究得出的結論)關於哪種空白字元風格有最好的可讀性。

例如,比較下列語法上等價的 C 語言代碼例子:

int i;
for(i=0;i<10;++i){
    printf("%d",i*i+i);
}

v.s.

int i;
for (i = 0; i < 10; ++i) {
    printf("%d", i * i + i);
}

制表符

使用製表鍵來建立空白字元,在不施加足夠關注時會造成特定的問題,因為依據使用的工具,甚至是使用者的偏好,制表點的位置可能不同。 如一個例子,一個程式設計師偏好4個制表位英語Tab Stops,將工具集設定成如此,然後用這些去格式化代碼。

int     ix;     // Index to scan array
long    sum;    // Accumulator for sum

另一個程式設計師偏好8個制表位,並將工具集設定成如此。當其他人檢查原來那個人的代碼時,他們可能會發現很難讀。

int             ix;             // Index to scan array
long    sum;    // Accumulator for sum

一種對這個問題廣泛使用的解決方法可能包含不為對齊使用製表鍵,或制定必須設定成幾個制表位的規則。注意制表符在一貫的情況下工作良好,限制在局部縮排上,並且不用來對齊:

class MyClass {
	int foobar(
		int qux, // first parameter
		int quux); // second parameter
	int foobar2(
		int qux, // first parameter
		int quux, // second parameter
		int quuux); // third parameter
};

參見

  1. ^ PEP 0008 -- Style Guide for Python Code. python.org. [2022-08-02]. (原始內容存檔於2018-07-13).