巧用 do...while(0) 改善代碼結(jié)構(gòu)

本文所討論的技巧都是為了避免過(guò)深的嵌套,來(lái)源于 bestswifter 的分享

有時(shí)候,if 和 else 的兩個(gè)分支,體量是完全不對(duì)等的,尤其是在函數(shù)的開(kāi)頭,我們經(jīng)常會(huì)對(duì)一些重要的前提條件做校驗(yàn),如果校驗(yàn)不通過(guò)就不會(huì)做任何后續(xù)的操作:

- (NSString *)handleString:(NSString *)str {
    if (![str isKindOfClass:[NSString class]]) {
        return nil;
    }
    else {
        // 以下省略 800 字
    }
}

可見(jiàn)這個(gè)簡(jiǎn)單的判斷就消耗了一個(gè)縮進(jìn),如果后續(xù)再有多個(gè)判斷,代碼層級(jí)就變得非常惡心,所以正確的做法如下:

- (NSString *)handleString:(NSString *)str {
    if (![str isKindOfClass:[NSString class]]) {
        return nil;
    }
    if(str.length <= 0) {
        return nil;
    }
   
    // ........ 省略多個(gè)判斷
    
    // 這里開(kāi)始寫(xiě)處理邏輯
}

這種做法在 Swift 面有更直接的語(yǔ)義,即 guard 關(guān)鍵字,相信大部分讀者都知道了。

我們思考一下這里的本質(zhì),它其實(shí)是利用了 return 關(guān)鍵字提前終止了代碼的執(zhí)行,然而 return 是作用在整個(gè)函數(shù)上的,只不過(guò)可以起到阻止后續(xù)代碼的執(zhí)行的作用,而且恰好在這里沒(méi)有副作用而已。

只是不是不好理解?沒(méi)關(guān)系,看這個(gè)例子,我改兩句注釋:

- (NSString *)handleString:(NSString *)str {
    if (![str isKindOfClass:[NSString class]]) {
        return nil;
    }
    if(str.length <= 0) {
        return nil;
    }
   
    // ........ 省略多個(gè)判斷
    
    // 第一部分邏輯依賴于前面的判斷,只有判斷通過(guò)的時(shí)候才執(zhí)行
    // 第二部分邏輯不依賴于前面的判斷,無(wú)論判斷是否通過(guò)都要執(zhí)行
}

現(xiàn)在的函數(shù)有兩部分邏輯,如果只有第一部分邏輯,使用 return 毫無(wú)問(wèn)題,然而第二部分邏輯要求無(wú)論是否通過(guò)前置校驗(yàn)都要執(zhí)行,顯然 return 關(guān)鍵字就不合適了。

不合適的本質(zhì)原因剛剛說(shuō)了,因?yàn)?return 影響的是整個(gè)函數(shù)的執(zhí)行流程,它在第一段 demo 中能工作只是一個(gè)美麗的巧合。

如果能從這個(gè)角度去思考為什么 return 不行,那么解決方案就很簡(jiǎn)單了:既然 return 影響外層的代碼塊邏輯,那就構(gòu)造一個(gè)臨時(shí)的代碼塊就行了:

- (NSString *)handleString:(NSString *)str {
    do {
        if (![str isKindOfClass:[NSString class]]) {
            break;
        }
        if(str.length <= 0) {
            break;
        }
        
         // ........ 省略多個(gè)判斷
        
        // 第一部分邏輯依賴于前面的判斷,只有判斷通過(guò)的時(shí)候才執(zhí)行
        
    }while (0);
    
    // 第二部分邏輯不依賴于前面的判斷,無(wú)論判斷是否通過(guò)都要執(zhí)行
}

在這個(gè) while 循環(huán)里,用 break 就可以退出這個(gè)臨時(shí)構(gòu)造的代碼塊,也不會(huì)影響其它邏輯。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 34,840評(píng)論 18 399
  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young閱讀 4,203評(píng)論 1 10
  • 原文來(lái)自theNextWeb,作者Jerry Cao,一位就職于UXPin的內(nèi)容策略專家,轉(zhuǎn)載請(qǐng)先詢問(wèn)筆者意見(jiàn)并注...
    IrioLee閱讀 3,003評(píng)論 1 57
  • 近期,同濟(jì)大學(xué)和特贊聯(lián)合發(fā)起了一次圓桌討論,這次討論讓人感覺(jué)到是一場(chǎng)“危機(jī)討論”,在人工智能快速發(fā)展的今天,如何設(shè)...
    文藝青年盒盒閱讀 666評(píng)論 3 1
  • 農(nóng)歷九月十四,晴 最近看 《朗讀手冊(cè)》。 一本結(jié)婚前買(mǎi)的書(shū),當(dāng)時(shí)是薛瑞萍特級(jí)語(yǔ)文教師推薦的。那個(gè)時(shí)候她就是我的偶像...
    玲萍閱讀 172評(píng)論 0 1

友情鏈接更多精彩內(nèi)容