Ash Furrow在關於避免不必要的代碼縮進問題上這樣說:
自從第一年一個睿智的高年級的學生向我展示了如何在代碼里避免不必要的縮進后,我一直都保持著這種做法。我並不去糾正已有的代碼,因為這並不能改善程序的性能,我只是在些新的程序里避免不必要的空格縮進。
我還有另外一個很相似的習慣,但並不是關於縮進的,而是關於避免嵌套。乍一看,這兩個問題很相似(連視覺上都有縮進的表現)。但核心問題不一樣,前者是關於程序書寫問題的,後者是語義上的。
避免嵌套這種編寫風格最大的好處是bailing early。跟深層次的嵌套你的語句(這樣會同時導致你深度的縮進)的做法相反,簡化你的語句,把你的程序設計成最終要執行的語句儘可能的少,簡單的越容易讓人理解越好。觀察一下下面的例子:
- (void)doSomethingWithString:(NSString *)s { if (nil != s) { if ([s length] > 0) { NSLog(@"%@", s); } } } // 相對於 - (void)doSomethingWithString:(NSString *)s { if (nil == s) return; if (![s length]) return; NSLog(@"%@", s); }
細心的讀者可能會注意到一些問題:
- 我的第二個例子實際比第一個要長。
- 第二個例子更可讀。想象一下如果在主方法執行前你有5個判斷條件要檢查,你嵌套出來的語句將會有多麼的可怕?
- 這個組合的
nil
和length
檢查在這個特殊的例子中是沒必要的(因為返回nil
這樣的消息時,nil
的值是0x0
,等於0
,對於空字元或 nil 調用[s length]
都返回0
)。這是專門這樣做的,為了說明問題。
當然,這種特別的”bailing early”的風格在處理內存管理上會有一些其他方面的問題。如果你使用這種風格,某些時候你必須做一些額外的操作。也就是你有時候會過於頻繁的使用內存自動釋放(autorelease),或你需要在程序的多個地方使用重複的釋放代碼來避免對象分配泄漏。在真實工作中這種情況很少見,但我想你還是要把這點記在心裡。