代码风格

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

代码风格(英语: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 缩进风格用回车分组而不是缩进。和所有以上的比较:

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).