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