原文:http://webkit.org/coding/coding-style.html
翻译:子丰
邮件:[email protected]
时间:2009年3月27日
缩进
1、使用空格,而不使用Tab,Tab只在那些语义需要Tab支持的文件中出现,比如Mikefile。
2、缩进为4个空格。
正确:
int main()
{
return 0;
}
错误:
int main()
{
return 0;
}
3、在头文件中,名字空间(namespace)中的代码需要缩进。
正确:
// Document.h
namespace WebCore {
class Document {
Document();
...
};
} // namespace WebCore
错误:
// Document.h
namespace WebCore {
class Document {
Document();
...
};
} // namespace WebCore
4、在实现文件中(.cpp、.c 或.mm),名字空间中的代码不需要缩进
正确:
// Document.cpp
namespace WebCore {
Document::Document()
{
...
}
} // namespace WebCore
错误:
// Document.cpp
namespace WebCore {
Document::Document()
{
...
}
} // namespace WebCore
5、case标签对齐于switch语句,case语句需要缩进。
正确:
switch (condition) {
case fooCondition:
case barCondition:
i++;
break;
default:
i--;
}
错误:
switch (condition) {
case fooCondition:
case barCondition:
i++;
break;
default:
i--;
}
6、同级的跨行布尔表达式,将布尔运算符放在代码行的左边,而不是右边。
正确:
return attr->name() == srcAttr
|| attr->name() == lowsrcAttr
|| (attr->name() == usemapAttr && attr->value().domString()[0] != '#');
错误:
return attr->name() == srcAttr ||
attr->name() == lowsrcAttr ||
(attr->name() == usemapAttr && attr->value().domString()[0] != '#');
空格
1、在一元运算符周围不放置空格
正确:
i++;
错误:
i ++;
2、在二元和三元运算符周围放置空格
正确:
y = m * x + b;
f(a, b);
c = a | b;
return condition ? 1 : 0;
错误:
y=m*x+b;
f(a,b);
c = a|b;
return condition ? 1:0;
3、在控制语句和括号之间留一个空格
正确:
if (condition)
doIt();
错误:
if(condition)
doIt();
4、函数与括号之间不放置空格,括号与括号里的内容之间不放置空格
正确:
f(a, b);
错误:
f (a, b);
f( a, b );
断行
1、每一个语句一行。
正确:
x++;
y++;
if (condition)
doIt();
错误:
x++; y++;
if (condition) doIt();
2、else 语句紧跟在它前面的}括号之后
正确:
if (condition) {
...
} else {
...
}
错误:
if (condition) {
...
}
else {
...
}
3、当前面的if语句包含一个return语句时,后面的else if 语句应该写成if 语句
正确:
if (condition) {
...
return someValue;
}
if (condition) {
...
}
错误:
if (condition) {
...
return someValue;
} else if (condition) {
...
}
花括号:{ }
1、函数定义:每一个花括号独立一行
正确:
int main()
{
...
}
错误:
int main() {
...
}
2、其他花括号:左花括号“{”位于前面的代码行之末,右花括号“}”独立一行。
正确:
class MyClass {
...
};
namespace WebCore {
...
}
for (int i = 0; i < 10; i++) {
...
}
错误:
class MyClass
{
...
};
3、控制语句只有一行则不需要花括号
正确:
if (condition)
doIt();
错误:
if (condition) {
doIt();
}
4、控制语句块如果为空,则需要一对空的花括号:
正确:
for ( ; current; current = current->next) { }
错误:
for ( ; current; current = current->next);
Null, false and 0
1、在C++里,空指针将被写作0,在C里,空指针被写作NULL,在Objective-C和Objective-C++里,分别与C或C++相同,只是,在Objective-C 用nil他代替null。
2、C++和C里的布尔值写成true和false,Objective-C里的布尔值写成YES和NO。
3、测试“真/假(true/false),空/非空(null/non-null),零/非零(zero/non-zero)”时,不需要比较。
正确:
if (condition)
doIt();
if (!ptr)
return;
if (!count)
return;
错误:
if (condition == true)
doIt();
if (ptr == NULL)
return;
if (count == 0)
return;
4、在Objective-C里,实例化的变量自动初始化为0,在初始化方法里,不需要再添加初始化为nil或NO的代码。
标识符
1、在“类,结构体、协议,名字空间”标识符中,应该使用CamelCase风格的命名方式,即单词首字母大写,缩写词大写。在变量名或函数名中,单词首字母小写,缩写词小写。
正确:
struct Data;
size_t bufferSize;
class HTMLDocument;
String mimeType();
错误:
struct data;
size_t buffer_size;
class HtmlDocument;
String MIMEType();
2、使用完整单词,公认易懂的缩写词除外。
正确:
size_t characterSize;
size_t length;
short tabIndex; // more canonical
错误:
size_t charSize;
size_t len;
short tabulationIndex; // bizarre
3、C++ 数据成员加前缀“m_”。
正确:
class String {
...
short m_length;
};
错误:
class String {
...
short length;
};
4、Objective-C 实例变量加前缀“_”。
正确:
@class String
...
short _length;
@end
错误:
@class String
...
short length;
@end
5、布尔变量前加“is”或“did”单词。
正确:
bool isValid;
bool didSendData;
错误:
bool valid;
bool sentData;
6、在设值函数名前加“set”,取值函数名前不加。设值函数名与取值函数名应该与被设值或取值的变量名匹配。
正确:
void setCount(size_t); // sets m_count
size_t count(); // returns m_count
错误:
void setCount(size_t); // sets m_theCount
size_t getCount();
7、函数名使用描述性动词
正确:
bool convertToASCII(short*, size_t);
错误:
bool toASCII(short*, size_t);
8、函数声明时,去掉无意义的形式参数变量
正确:
void setCount(size_t);
错误:
void setCount(size_t count);
9、Objective-C函数名应该遵从Cocoa命名指南。——他们读起来像短句并且每个选择符应该以小子字母开头。
10、枚举成员使用开头大写字母的InterCaps命名方法。
11、尽可能使用const,而不是#define;尽可能使用inline函数,而不是宏。
12、定义常量时,单词应该全部大写,单词之间用下划线分开。
13、扩展为函数调用或非常量计算的宏,都应该像函数一样命名,即使没有参数(一些像ASSERT的宏例外),应该用圆括号“()”结束。注意,通常在这种情况下,使用inline函数来代替宏。
正确:
#define WBStopButtonTitle() /
NSLocalizedString(@"Stop", @"Stop button title")
错误:
#define WB_STOP_BUTTON_TITLE /
NSLocalizedString(@"Stop", @"Stop button title")
#define WBStopButtontitle /
NSLocalizedString(@"Stop", @"Stop button title")
14. #define, #ifdef头文件保护宏命名应该与文件名相同,用下划线“_”代替点“.”
正确:
// HTMLDocument.h
#ifndef HTMLDocument_h
#define HTMLDocument_h
错误:
// HTMLDocument.h
#ifndef _HTML_DOCUMENT_H_
#define _HTML_DOCUMENT_H_
其他标点符号的使用
1. C++类的构造函数使用C++初始化语法初始化类的成员变量。每个成员单独占据一行并且缩进,冒号或逗号放在行的最前面。
正确:
MyClass::MyClass(Document* doc)
: MySuperClass()
, m_myMember(0)
, m_doc(doc)
{
}
MyOtherClass::MyOtherClass()
: MySuperClass()
{
}
错误:
MyClass::MyClass(Document* doc) : MySuperClass()
{
m_myMember = 0;
m_doc = doc;
}
MyOtherClass::MyOtherClass() : MySuperClass() {}
2. 在非C++代码中,指针类型书写时,在类型和*之间留一个空格(*更接近标识符)。
3. 在C++代码中,不管指针类型还是引用类型,书写时,在类型名和*或&之间没有空格。
正确:
Image* SVGStyledElement::doSomething(PaintInfo& paintInfo)
{
SVGStyledElement* element = static_cast<SVGStyledElement*>(node());
const KCDashArray& dashes = dashArray();
错误:
Image *SVGStyledElement::doSomething(PaintInfo &paintInfo)
{
SVGStyledElement *element = static_cast<SVGStyledElement *>(node());
const KCDashArray &dashes = dashArray();
#include语句
1. 所有实现文件都必须首先包含“config.h”文件,所有头文件都不包含“config.h”文件。
正确:
// RenderLayer.h
#include "Node.h"
#include "RenderObject.h"
#include "RenderView.h"
错误:
// RenderLayer.h
#include "config.h"
#include "RenderObject.h"
#include "RenderView.h"
#include "Node.h"
2. 所有实现文件必须在包含“config.h”文件之后,包含主头文件。举例如:Node.cpp应该在包含其他文件之前,包含Node.h文件。这将保证每个头文件完全被测试到。这也将确保每个头文件在不被其他头文件包含的情况下被编译。
3. 其他#include语句应该排序(区分大小写,可以使用命令行排序工具或Xcode排序命令)。按逻辑顺序组织他们,请勿干扰。
正确:
// HTMLDivElement.cpp
#include "config.h"
#include "HTMLDivElement.h"
#include "Attribute.h"
#include "HTMLElement.h"
#include "QualifiedName.h"
错误:
// HTMLDivElement.cpp
#include "HTMLElement.h"
#include "HTMLDivElement.h"
#include "QualifiedName.h"
#include "Attribute.h"