怎樣避免“if”嵌套

來源:互聯網
上載者:User

標籤:stackoverflow   c   if   編程   boolean   

前幾日在瀏覽stackoverflow網站時,偶然看到別人提的“How to avoid ‘if’ chains” 的問題,覺得這是一個編程人員在編程時很容易就碰到的問題,而且我自己在看一些源碼時也遇到過這種編程方式,因此,對這個問題進行一點總結。

if嵌套的情況很多,下面列出一些情況,並給出了相對來說比較簡潔的書寫方式以供參考:

1、使用一個guard來使用代碼變得平坦

a、代碼如下:

if (ok){    DoSomething();}else{    _log.Error("oops");    return;}

可以替換成:

if (!ok){    _log.Error("oops");    return;} DoSomething(); //notice how this is already farther to the left than the example above

b、代碼如下:

ok = DoSomething1();if (ok){    ok = DoSomething2();    if (ok)    {        ok = DoSomething3();        if (!ok)        {            _log.Error("oops");  //Tip of the Arrow            return;        }    }    else    {       _log.Error("oops");       return;    }}else{    _log.Error("oops");    return;}

可以改寫成:

ok = DoSomething1();if (!ok){    _log.Error("oops");    return;} ok = DoSomething2();if (!ok){    _log.Error("oops");    return;} ok = DoSomething3();if (!ok){    _log.Error("oops");    return;} ok = DoSomething4();if (!ok){    _log.Error("oops");    return;}

2、最後有非條件執行代碼的情況,虛擬碼如下:

bool conditionA = executeStepA();if (conditionA){    bool conditionB = executeStepB();    if (conditionB){        bool conditionC = executeStepC();        if (conditionC){            ...        }    }}executeThisFunctionInAnyCase();

函數executeStepX若且唯若前面的條件成立時才執行,而函數executeThisFunctionInAnyCase則在最後必需執行,而不管其它條件是否成立。

a、使用條件與(&&),利用條件短路的特性

if (executeStepA() && executeStepB() && executeStepC()){    ...}executeThisFunctionInAnyCase();

b、使用finally

try{bool conditionA = executeStepA();if (!conditionA) return;bool conditionB = executeStepB();if (!conditionB) return;bool conditionC = executeStepC();if (!conditionC) return;}finally{    executeThisFunctionInAnyCase();}

c、將條件執行用一個函數包起來

void foo(){  bool conditionA = executeStepA();  if (!conditionA) return;  bool conditionB = executeStepB();  if (!conditionB) return;  bool conditionC = executeStepC();  if (!conditionC) return;}void bar(){  foo();  executeThisFunctionInAnyCase();}

d、使用goto語句

int foo() {    int result = /*some error code*/;    if(!executeStepA()) goto cleanup;    if(!executeStepB()) goto cleanup;    if(!executeStepC()) goto cleanup;    result = 0;cleanup:    executeThisFunctionInAnyCase();    return result;}

e、利用條件的傳遞

bool condition = true; // using only one boolean variableif (condition) condition = executeStepA();if (condition) condition = executeStepB();if (condition) condition = executeStepC();...executeThisFunctionInAnyCase();

f、使用異常

try {    executeStepA();    executeStepB();    executeStepC();}catch (...) {executeThisFunctionInAnyCase();}

g、使用假迴圈

while(true){    bool conditionA = executeStepA();if (!conditionA) break;bool conditionB = executeStepB();if (!conditionB) break;bool conditionC = executeStepC();if (!conditionC) break;    break;  //important}executeThisFunctionInAnyCase();

h、利用對象的生命週期

class MyContext{   ~MyContext()   {        executeThisFunctionInAnyCase();   }}void MainMethod(){    MyContext myContext = new MyContext();    bool conditionA = executeStepA();if (!conditionA) return;bool conditionB = executeStepB();if (!conditionB) return;bool conditionC = executeStepC();if (!conditionC) return;    //DoSomethingNoMatterWhat will be called when myContext goes out of scope}

其中,最簡單的是利用條件短路,而最複雜的是利用對象的生命週期。總結了這此情況和方法供大家參考,當然,可能還有很多其它的情況和處理方法,希望讀者踴躍留言。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.