簡體   English   中英

使用嵌套的if語句來構造代碼

[英]Using nested if statements to structure code

我試圖以一種可讀的方式來構造我的代碼。 我已經讀過一種方法,如下所示:

if(Init1() == TRUE)
{
    if(Init2() == TRUE)
    {
        if(Init3() == TRUE)
        {
            ...
            Free3();
        }
        Free2();
    }
    Free1();
}

我喜歡這種處理方式,因為它將每個FreeX在其匹配的InitX循環中,但是如果嵌套超過三層,它將很快變得不可讀,並超過80列。 可以將許多功能分解為多個功能,以免發生這種情況,但是為了避免太多層次的嵌套而分解一個功能似乎很愚蠢。 特別是,請考慮對整個類進行初始化的函數,其中該初始化需要十個或更多函數調用。 那是十層或更多層的嵌套。

我敢肯定,我想得太多了,但是上面我缺少一些基本的東西嗎? 能否以可讀的方式進行深度嵌套? 還是以某種方式進行了重組,同時將每個FreeX在自己的InitX循環中?

順便說一句,我意識到上面的代碼可以壓縮為if(Init1() && Init2()... ,但是該代碼只是一個例子,在每個InitX調用之間會有其他代碼可以防止這種壓縮。

由於包含了C ++標記,因此應該使用RAII-資源獲取正在初始化。 有很多很好的在線資源解釋了這個概念,這將使很多與資源管理有關的事情變得更加容易。

我敢肯定,我想得太多了,但是上面我缺少一些基本的東西嗎? [...]還是以某種方式進行了重組,同時將每個FreeX保留在自己的InitX循環中?

是。 這是一個代碼的教科書案例,將從RAII代碼中受益匪淺:

而不是構造:

if(init(3) == TRUE)
{
    free3();
}

考慮一下:

raii_resource3 r3 = init3(); // throws exception if init3 fails
                             // free3 called internally
                             // by raii_resource3::~raii_resource3

您的完整代碼將變為:

raii_resource1 r1 = init1();
raii_resource2 r2 = init2();
raii_resource3 r3 = init3();

您將沒有嵌套的ifs,您的代碼將清晰明了(並專注於肯定的情況)。

您將只需要為資源1、2和3編寫RAII包裝器。

正如其他人指出的,顯而易見的答案是RAII。 但是,如果在沒有RAII的情況下出現了過度深層嵌套的問題,那么您應該真正問問自己,您是否沒有使函數過於復雜。 一個函數很少包含超過十行(包括此類檢查)。 如果查看實際案例,您會發現分解功能幾乎總是更有意義。 即使使用RAII,每個函數通常也應該只有一個RAII類實例。 (當然也有例外;可以說,類似std::lock_guard類的東西不應該算在內。)

我建議使用的是switch語句。 當涉及到這樣的代碼時,我非常喜歡switch語句

希望這可以幫助。

switch (i) {
    case 1:
        // action 1
        break;
    case 2:
        // action 2
        break;
    case 3:
        // action 3
        break;
    default:
        // action 4
        break;
}

您可能聽說過gotos是邪惡的,但是如果您堅持使用c,那么使用gotos處理此類異常並沒有什么“骯臟”:

foo()
{
  if (!Init1())
    goto Error1;
  if (!Init2())
    goto Error2;
  ...
  ...
Error2:
  Free2();
Error1:
  Free1();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM