程序设计,代码的缩进和嵌套
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),或你需要在程序的多个地方使用重复的释放代码来避免对象分配泄漏。在真实工作中这种情况很少见,但我想你还是要把这点记在心里。