代碼風格指導

翻譯原文

date:20170802

介紹

本指導提供代碼約定,來規(guī)范Solidity的代碼瘩欺。本指導會不斷變化必盖,新的,有用的約定會不斷添加進來俱饿,舊的約定會被淘汰歌粥。
很多項目都想自己實現(xiàn)各自的風格指導。作為事件沖突拍埠,項目指定的風格要優(yōu)先考慮失驶。
本指導中的結(jié)構和很多約定都是遵從Python的pep8代碼風格指導
本指導的目標不是要規(guī)定寫solidity代碼的正確方法枣购,或者最好的方法突勇。目標是統(tǒng)一化。引用pep8的這個概念:

風格指導手冊是對統(tǒng)一化的規(guī)定坷虑。根據(jù)手冊,統(tǒng)一化編碼是很重要的埂奈。同個項目的代碼風格保持一致更加重要迄损。在模塊中統(tǒng)一化,或者函數(shù)中账磺,是最重要的芹敌。但是最重要的:需要知道什么時候要統(tǒng)一化——有時候不需要代碼風格指導。當有疑問的時候垮抗,要用你的判斷力氏捞。查看其它例子,然后決定哪種看起來會最好冒版。不要猶豫提問題液茎,請教別人。

代碼層級

縮進

每層縮進用4個空格。

Tabs和空格

空格是更期望的縮進方式捆等。
tabs和空格混合是要避免的滞造。

空行

solidity源碼的頂層描述要有兩個空行。
Yes:

contract A {
    ...
}


contract B {
    ...
}


contract C {
    ...
}

No:

contract A {
    ...
}
contract B {
    ...
}

contract C {
    ...
}

在合約中栋烤,函數(shù)用一行空行隔開谒养。
相關的只有一行的代碼,空行可以省略(例如虛擬合約的未實現(xiàn)的函數(shù))明郭。

Yes:

contract A {
    function spam();
    function ham();
}


contract B is A {
    function spam() {
        ...
    }

    function ham() {
        ...
    }
}

No:

contract A {
    function spam() {
        ...
    }
    function ham() {
        ...
    }
}
源碼編碼

更傾向于UTF-8 或者 ASCII編碼买窟。

imports

導入表達式應該總是被放置在文件的頂部。

Yes:

import "owned";


contract A {
    ...
}


contract B is owned {
    ...
}

No:

contract A {
    ...
}


import "owned";


contract B is owned {
    ...
}

函數(shù)的順序

排序有助于讀者可以方便的知道哪些函數(shù)是可以調(diào)用的薯定,且可以快速的找到構造函數(shù)和回調(diào)函數(shù)的定義始绍。
函數(shù)應該按照他們的可見性排序:

  • constructor
  • fallback 函數(shù)(如果有)
  • external
  • public
  • internal
  • private

constant函數(shù)放置分組的最后。

Yes:

contract A {
    function A() {
        ...
    }

    function() {
        ...
    }

    // External 函數(shù)
    // ...

    // External 的constant函數(shù)
    // ...

    // Public 函數(shù)
    // ...

    // Internal 函數(shù)
    // ...

    // Private 函數(shù)
    // ...
}

No:

contract A {

    // External 函數(shù)
    // ...

    // Private 函數(shù)
    // ...

    // Public 函數(shù)
    // ...

    function A() {
        ...
    }

    function() {
        ...
    }

    // Internal 函數(shù)
    // ...
}
表達式中的空格

在下列情況下應該避免額外的空格:

在圓括號沉唠,中括號或者大括號之間沒有空格疆虚,除了單行的函數(shù)描述。
Yes:

spam(ham[1], Coin({name: "ham"}));

No:

spam( ham[ 1 ], Coin( { name: "ham" } ) );

例外:

function singleLine() { spam(); }

在逗號满葛,分號之前径簿,沒有空格:

Yes:

function spam(uint i, Coin coin);

No:

function spam(uint i , Coin coin) ;

賦值應該要多于一個空格,或者和其他操作對齊
Yes:

x = 1;
y = 2;
long_variable = 3;

No:

x             = 1;
y             = 2;
long_variable = 3;

在回調(diào)函數(shù)中不要包含空格:
Yes:

function() {
    ...
}

No:

function () {
    ...
}
控制結(jié)構

大括號包圍的是合約的主體嘀韧,庫篇亭,函數(shù)和結(jié)構體,應該:

  • 在同一行中開始
  • 結(jié)束標簽要新建一行锄贷,并在他們各自的同個縮進層級的位置
  • 開始括號應該用單個空格隔開

Yes:

contract Coin {
    struct Bank {
        address owner;
        uint balance;
    }
}

No:

contract Coin
{
    struct Bank {
        address owner;
        uint balance;
    }
}

該建議同樣適用于控制體if,else,whilefor译蒂。

另外,在if,while谊却,for和代表條件的括號塊之間要有單個空格柔昼,條件和開始括號之間也有空格:

Yes:

if (...) {
    ...
}

for (...) {
    ...
}

NO:

if (...)
{
    ...
}

while(...){
}

for (...) {
    ...;}

對于只有一條語句的控制體,且都寫在一行中炎辨,可以省略花括號捕透。
Yes:

if (x < 10)
    x += 1;

No:

if (x < 10)
    someArray.push(Coin({
        name: 'spam',
        value: 42
    }));

對于有else或者else ifif塊,else應該和if的結(jié)束括號同一行碴萧。對唄其他區(qū)塊結(jié)構的規(guī)則乙嘀,這是一個例外。
Yes:

if (x < 3) {
    x += 1;
} else if (x > 7) {
    x -= 1;
} else {
    x = 5;
}


if (x < 3)
    x += 1;
else
    x -= 1;

No:

if (x < 3) {
    x += 1;
}
else {
    x -= 1;
}
函數(shù)聲明

對于簡短的函數(shù)的聲明破喻,推薦函數(shù)聲明和開始括號在同一行虎谢。
函數(shù)的閉合括號應該與函數(shù)聲明行有相同的縮進。

開始括號應該和函數(shù)聲明在同一行曹质。

Yes:

function increment(uint x) returns (uint) {
    return x + 1;
}

function increment(uint x) public onlyowner returns (uint) {
    return x + 1;
}

No:

function increment(uint x) returns (uint)
{
    return x + 1;
}

function increment(uint x) returns (uint){
    return x + 1;
}

function increment(uint x) returns (uint) {
    return x + 1;
    }

function increment(uint x) returns (uint) {
    return x + 1;}

函數(shù)的可見性婴噩,應該在任意自定義的修改器之前擎场。
Yes:

function kill() public onlyowner {
    selfdestruct(owner);
}

No:

function kill() onlyowner public {
    selfdestruct(owner);
}

對于長的函數(shù)聲明,推薦將每個參數(shù)都各自一行讳推,并且縮進和函數(shù)體一樣顶籽。參數(shù)關閉括號和函數(shù)體開始括號在同一行,縮進與函數(shù)聲明一致银觅。

Yes:

function thisFunctionHasLotsOfArguments(
    address a,
    address b,
    address c,
    address d,
    address e,
    address f
) {
    doSomething();
}

No:

function thisFunctionHasLotsOfArguments(address a, address b, address c,
    address d, address e, address f) {
    doSomething();
}

function thisFunctionHasLotsOfArguments(address a,
                                        address b,
                                        address c,
                                        address d,
                                        address e,
                                        address f) {
    doSomething();
}

function thisFunctionHasLotsOfArguments(
    address a,
    address b,
    address c,
    address d,
    address e,
    address f) {
    doSomething();
}

如果長的函數(shù)聲明有修改器礼饱,那么將修改器放置在單獨的行。
Yes:

function thisFunctionNameIsReallyLong(address x, address y, address z)
    public
    onlyowner
    priced
    returns (address)
{
    doSomething();
}

function thisFunctionNameIsReallyLong(
    address x,
    address y,
    address z,
)
    public
    onlyowner
    priced
    returns (address)
{
    doSomething();
}

No:

function thisFunctionNameIsReallyLong(address x, address y, address z)
                                      public
                                      onlyowner
                                      priced
                                      returns (address) {
    doSomething();
}

function thisFunctionNameIsReallyLong(address x, address y, address z)
    public onlyowner priced returns (address)
{
    doSomething();
}

function thisFunctionNameIsReallyLong(address x, address y, address z)
    public
    onlyowner
    priced
    returns (address) {
    doSomething();
}

對于構造函數(shù)究驴,如果父合約的構造函數(shù)需要參數(shù)镊绪,函數(shù)聲明比較長或者難于閱讀,應該將父類構造函數(shù)和修改器一樣洒忧,寫在新的行蝴韭。
Yes:

contract A is B, C, D {
    function A(uint param1, uint param2, uint param3, uint param4, uint param5)
        B(param1)
        C(param2, param3)
        D(param4)
    {
        // do something with param5
    }
}

No:

contract A is B, C, D {
    function A(uint param1, uint param2, uint param3, uint param4, uint param5)
    B(param1)
    C(param2, param3)
    D(param4)
    {
        // do something with param5
    }
}

contract A is B, C, D {
    function A(uint param1, uint param2, uint param3, uint param4, uint param5)
        B(param1)
        C(param2, param3)
        D(param4) {
        // do something with param5
    }
}

當聲明短函數(shù)中只有一個句表述,可以寫在一行中熙侍。

允許的:

function shortFunction() { doSomething(); }

這個函數(shù)聲明的指導手冊是想要提高可讀性榄鉴。作者應該有自己的判斷,手冊不會覆蓋函數(shù)聲明的所有情況蛉抓。

映射

TODO

變量聲明

數(shù)組的聲明庆尘,類型和方括號之間不能有空格。

Yes:

uint[] x;

No:

uint [] x;
其他建議
  • string應該用雙引號包圍巷送,而不是單引號驶忌。
    Yes:
str = "foo";
str = "Hamlet says, 'To be or not to be...'";

No:

str = 'bar';
str = '"Be yourself; everyone else is already taken." -Oscar Wilde';
  • 操作符兩端應該用單個空格隔開。
    Yes:
x = 3;
x = 100 / 10;
x += 3 + 4;
x |= y && z;

No:

x=3;
x = 100/10;
x += 3+4;
x |= y&&z;
  • 比其他操作符優(yōu)先級高的操作符要去掉空格笑跛。這是為了提高復雜表達式的可讀性付魔,你在操作符兩端,應該總是使用相同數(shù)量的空格符飞蹂。

Yes:

x = 2**3 + 5;
x = 2*y + 3*z;
x = (a+b) * (a-b);

No:

x = 2** 3 + 5;
x = y+z;
x +=1;

命名規(guī)范

當代碼廣泛使用几苍,命名約定是很重要的。不同約定的使用會傳遞重要的元信息陈哑,讓人覺得代碼不能馬上使用擦剑。
這里給出的命名推薦試圖提高代碼可讀性,但是他們不是規(guī)定芥颈,而是指導手冊,讓名字能夠傳遞更多的信息赚抡。
最后爬坑,代碼庫的統(tǒng)一化約定都是要優(yōu)先于本文列出的約定。

命名風格

為了避免產(chǎn)生困惑涂臣,下面的命名會使用不同的命名風格:

  • b(單個小寫字符)
  • B(單個大寫字符)
  • lowercase
  • lower_case_with_underscores
  • UPPERCASE
  • UPPER_CASE_WITH_UNDERSCORES
  • CapitalizedWords(或者CapWords)
  • mixedCase(和CapitalizedWords不同的是第一個字母是小寫字母)
  • Capitalized_Words_With_Underscores

注意:當對縮略語用CapWords規(guī)則命名的時候盾计,所有縮略字母都要大寫售担。所以HTTPServerError會比HttPServerError更好。

應該避免的名字
  • l - 小寫字母 el
  • O - 大寫字母 oh
  • I - i的大寫字母

不要使用這些單個字母的命名署辉。因為他們經(jīng)常會分不清是字符還是數(shù)字族铆。

合約和庫的名稱

合約和庫的名稱應該使用CapWords風格。

事件

事件應該使用CapWords風格哭尝。

函數(shù)名字

函數(shù)命應該使用mixedCase風格哥攘。

函數(shù)參數(shù)

當寫庫函數(shù)來操作一個自定義的結(jié)構體的時候,結(jié)構體應該是第一個參數(shù)材鹦,并且總是命名為self逝淹。

局部變量和狀態(tài)變量

使用mixedCase風格。

靜態(tài)變量

靜態(tài)變量命名應該使用大寫字母桶唐,并且單詞之間要用下劃線隔開栅葡。(例如,MAX_BLOCKS

修改器

使用mixedCase風格尤泽。

避免沖突
  • single_trailing_underscore_

這個約定用于自定義變量和內(nèi)建變量或保留名稱有命名沖突的時候欣簇。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市坯约,隨后出現(xiàn)的幾起案子熊咽,更是在濱河造成了極大的恐慌,老刑警劉巖鬼店,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件网棍,死亡現(xiàn)場離奇詭異,居然都是意外死亡妇智,警方通過查閱死者的電腦和手機滥玷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來巍棱,“玉大人惑畴,你說我怎么就攤上這事『结悖” “怎么了如贷?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長到踏。 經(jīng)常有香客問我杠袱,道長,這世上最難降的妖魔是什么窝稿? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任楣富,我火速辦了婚禮,結(jié)果婚禮上伴榔,老公的妹妹穿的比我還像新娘纹蝴。我一直安慰自己庄萎,他們只是感情好,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布塘安。 她就那樣靜靜地躺著糠涛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪兼犯。 梳的紋絲不亂的頭發(fā)上忍捡,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天,我揣著相機與錄音免都,去河邊找鬼锉罐。 笑死,一個胖子當著我的面吹牛绕娘,可吹牛的內(nèi)容都是我干的脓规。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼险领,長吁一口氣:“原來是場噩夢啊……” “哼荆烈!你這毒婦竟也來了阿纤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎腰湾,沒想到半個月后客们,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體犁珠,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡捧韵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了秤掌。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片愁铺。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖闻鉴,靈堂內(nèi)的尸體忽然破棺而出茵乱,到底是詐尸還是另有隱情,我是刑警寧澤孟岛,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布瓶竭,位于F島的核電站,受9級特大地震影響渠羞,放射性物質(zhì)發(fā)生泄漏斤贰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一次询、第九天 我趴在偏房一處隱蔽的房頂上張望腋舌。 院中可真熱鬧,春花似錦渗蟹、人聲如沸块饺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽授艰。三九已至,卻和暖如春世落,著一層夾襖步出監(jiān)牢的瞬間淮腾,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工屉佳, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留谷朝,地道東北人。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓武花,卻偏偏與公主長得像圆凰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子体箕,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容

  • iOS編程規(guī)范0規(guī)范 0.1前言 為??高產(chǎn)品代碼質(zhì)量,指導廣大軟件開發(fā)人員編寫出簡潔专钉、可維護、可靠累铅、可 測試跃须、高效...
    iOS行者閱讀 4,455評論 21 35
  • 推薦文章:禪與 Objective-C 編程藝 前言 為??高產(chǎn)品代碼質(zhì)量,指導廣大軟件開發(fā)人員編寫出簡潔、可維護娃兽、...
    WolfTin閱讀 2,757評論 0 1
  • 代碼格式 使用空格而不是制表符 Tab 不要在工程里使用 Tab 鍵菇民,使用空格來進行縮進。在 Xcode > Pr...
    small_Sun閱讀 1,360評論 1 3
  • 示例 下面是一個示例頭文件投储,演示了@interface聲明的正確注釋和間隔 一個示例源文件第练,演示了一個接口的@ i...
    我是Damo閱讀 1,993評論 2 5
  • 《留春令》 滿眼樓高冲泥,影單踟躕驹碍。 難見西窗燭。 哪寫紫毫書凡恍? 唱清風志秃、無限事。 月月愧領五斗米嚼酝, 心卻行萬里浮还。 樓...
    黑星水生閱讀 220評論 0 0