if嵌套的代碼風格哪種好?

有一段子程序, 需要做一系列的事情, 必須上一函數成功了才能繼續執行下一個函數.全部成功才返回成功.

下面列出了兩種嵌套代碼的風格, 我想請教一下哪種風格好?

# 風格1
def do_big_thing_1():
res_1 = do_something_1()
if res_1:
res_2 = do_something_2()
if res_2:
res_3 = do_something_3()
if res_3:
return True # 全部成功
else:
return False
else:
return False
else:
return False

# 風格2
def do_big_thing_2():
res_1 = do_something_1()
if not res_1:
return False

res_2 = do_something_2()
if not res_2:
return False

res_3 = do_something_3()
if not res_3:
return False

return True # 全部成功

我一直使用第2種風格. 我覺得從易讀和維護角度來說第2種風格都完勝, 可是我在看別人源碼的時候卻很少見風格2的代碼. 難道我還是 too young, too simple...


第一種是蛋疼,不過用第二種我會不寫臨時變數,而且就例子來說我會直接用and連起來。


其實可以直接return f1() and f2() and f3() ..一樣是從左至右依次做 一個不成功就停止並返回false

基本上絕大多數語言都這個執行邏輯

當然,其實還有函數指針之類的辦法,都可以比你寫的2更簡便。

至於1那種寫法,我真只在小學生初中生里見過。


我來開個腦洞,

return (do_something_1()
do_something_2()
do_something_3());

假如編譯器嚴格按照你的函數書寫順序的話,且第一個為false之後將不會運行後續的。

我不認識這門語言,當我胡言亂語吧。


我的代碼都是Early Return的。不過通常會注釋一下,因為early return的那個return不是太明顯。

其實我覺得語言應該要提供 return if 的語法糖。。。

另外,第一種應該寫作:

def do_big_thing_1():
res_1 = do_something_1()
if res_1:
res_2 = do_something_2()
if res_2:
res_3 = do_something_3()
if res_3:
return True # 全部成功
return False

這裡沒有用邏輯運算主要是因為考慮到你的do_something很可能是一組語句而不是一條。


你知道自己做的是對的,但是需要別人肯定你做的是對的。

《重構-改善既有代碼的設計》Martin Fowler 重構 (豆瓣)

9.5 Replace Nested Conditional with Guard Clauses (以衛語句取代嵌套條件表達式)

看來你做的是對的。

《Linux kernel coding style》Linus Torvalds

Chapter 1: Indentation

If you need more than 3 levels of indentation, you』re screwed anyway, and should fix your program.

嗯,應該是對的。


為了調試方便和看著舒服,最好還是包個函數出來


我覺得如果是死板一些的Csharp的話 應該有第三種

先定義一個bool 的返回值

然後在第一種風格的 if 中設置 true 和 false ,最後返回這個值

這種寫法會容易被IDE重構,抽取部分邏輯成為函數。

沒有這種優勢的話 第一種就是蛋疼


題主,堅持自己,第二種明顯好。用第一種的可能是因為,沒有else腦子轉不過來。儘早return 好習慣。


建議用do {} while(false) ; 可以避免ifelse嵌套。


歪樓,Ruby的糖很甜。

def do_big_thing_3
return false unless do_something_1
return false unless do_something_2
do_something_3 ? true : false
end


這不是傳說中的 maybe monad 嘛。。。。


用Monad最好(逃


你這個例子太簡單了,問題是if-else中一般都有其他相關的邏輯。if-else 組劃分開了這些成對的邏輯。

一般我還會在後面加一個 assert False # Unreachable


反正我喜歡嵌套淺的。。。


def do_big_thing_1():
res_1 = do_something_1()
if do_something_1() and do_something_2() and do_something_3():
return true
else:
return False

其實怎樣寫都可以啦. 無所謂啦. 看你覺得怎樣比較適合當前理解吧.

或許1,2,3,是strictly sequential 的呢? 那麼1也無所厚非吧..


這種情況一般我都寫成

def do_big_thing1():
return do_thing1() and do_thing2() and do_thing3()

當然前提是保證 do_thing1( ), do_thing2( ), do_thing3( ) 的返回值都設計良好,同時正確處理 exception 。。。

要是函數名太長的話,就看要不要堅持 pep8了。。。


第二種


用do{}while(false)


我一般用、||、!、?、:哈哈哈哈


我的話可能會這麼寫(需要goto):

If (something1)

{

goto cleanup;

}

//省略if若干個

cleanup:

return;

以上。


推薦閱讀:

你有哪些想要分享的 PyCharm 使用技巧?
你見過哪些令你瞠目結舌的 Python 代碼技巧?
Windows 的 file handle 為什麼譯為「文件句柄」?
你見過哪些令人瞠目結舌的php代碼技巧?
如何看待 Windows 的 C++ 包管理器 vcpkg?

TAG:編程 | 代碼風格 |