原文: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"