代码的缩进和嵌套

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);
        }
        

细心的读者可能会注意到一些问题:

  1. 我的第二个例子实际比第一个要长。
  2. 第二个例子更可读。想象一下如果在主方法执行前你有5个判断条件要检查,你嵌套出来的语句将会有多么的可怕?
  3. 这个组合的nillength 检查在这个特殊的例子中是没必要的(因为返回nil这样的消息时,nil的值是0x0,等于0,对于空字符或 nil 调用[s length]都返回0)。这是专门这样做的,为了说明问题。

当然,这种特别的”bailing early”的风格在处理内存管理上会有一些其他方面的问题。如果你使用这种风格,某些时候你必须做一些额外的操作。也就是你有时候会过于频繁的使用内存自动释放(autorelease),或你需要在程序的多个地方使用重复的释放代码来避免对象分配泄漏。在真实工作中这种情况很少见,但我想你还是要把这点记在心里。

[英文原文:Code Indentation and Nesting ]
分享这篇文章:

17 Responses to 代码的缩进和嵌套

  1. suigara says:

    具体情况具体分析吧

    不过我自己也是喜欢这种风格的

  2. 代码回音 says:

    读的时候后面的容易
    自己写的时候 估计就前面那个了

  3. Daniel says:

    更倾向于第二种,可惜啊,很多所谓的编程规范明文规定,函数只有一个出口。而这句话大多数情况,被理解成函数只能有一个return。

  4. rexfire says:

    goto可读性更强。你用吧!

  5. rexfire says:

    大家看一下这篇文章,这两个外国人肯定有一个在扯淡!

    《只要一个返回语句》
    http://www.aqee.net/2011/03/23/a-return-to-good-code/

    不要盲目崇拜外国人,还是要靠自己判断!

  6. haitao says:

    也经常使用第二种风格减少缩进程度
    不过,逻辑的确比较散乱了

  7. PlayInLife says:

    就是传说中的减少圈复杂度吧

  8. kevin says:

    Google Code Style Guide是一流标准,没有之一。

  9. jaxer says:

    文中:
    自从第一年一个睿智的高年级的学生向我展示了如何在代码里避免不必要的缩进后
    有人知道原文在哪里吗?搜索到的都是此文

  10. Chonger.R says:

    还曾经有人在本论坛说过,一个方法里不要用多个return语句。return属于强制性中断。

  11. Yonghang Jiang says:

    return其实就是一个目标位置固定的goto而已。目标位置是函数的最后。
    所以完全可以在函数的最后几行放一个Exit标签,一切return都改成goto到那个标签,而在那个标签之后进行内存的释放动作,然后return。为了避免goto混乱,用一个宏包裹goto关键字。
    这是我刚参加工作时从国内某著名软件公司学到的。

发表评论

邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据