巧用 do...while(0) 改善代码结构

本文所讨论的技巧都是为了避免过深的嵌套

有时候,if 和 else 的两个分支,体量是完全不对等的,尤其是在函数的开头,我们经常会对一些重要的前提条件做校验,如果校验不通过就不会做任何后续的操作:

  • - (NSString *)handleString:(NSString *)str {
  • if (![str isKindOfClass:[NSString class]]) {
  • return nil;
  • }
  • else {
  • // 以下省略 800 字
  • }
  • }

可见这个简单的判断就消耗了一个缩进,如果后续再有多个判断,代码层级就变得非常恶心,所以正确的做法如下:

  • - (NSString *)handleString:(NSString *)str {
  • if (![str isKindOfClass:[NSString class]]) {
  • return nil;
  • }
  • if ([str length] <= 0) {
  • return nil
  • }
  • // ...... 省略多个判断
  • // 这里开始写处理逻辑
  • }

这种做法在 Swift 里面有更直接的语义,即 guard 关键字,相信大部分读者都知道了。

我们思考一下这里的本质,它其实是利用了 return 关键字提前终止了代码的执行,然而 return 是作用在整个函数上的,只不过可以起到阻止后续代码的执行的作用,而且恰好在这里没有副作用而已。

是不是不好理解?没关系,看这个例子,我改两句注释:

```objc

  • (NSString *)handleString:(NSString *)str {
    if (![str isKindOfClass:[NSString class]]) {
top Created with Sketch.