代码之家  ›  专栏  ›  技术社区  ›  Dean J

强制使用大括号

  •  17
  • Dean J  · 技术社区  · 15 年前

    作为我写回的代码标准文档的一部分,我强制“必须始终对循环和/或条件代码块使用大括号,即使(特别是)它们只是一行。”

    例子:

    // this is wrong
    if (foo) 
        //bar
    else 
        //baz
    while (stuff)
        //things
    
    // This is right.
    if (foo) {
        // bar
    } else {
        // baz
    }
    while (things) {
        // stuff
    }
    

    当你一句话都没说出来,然后有人说出来的时候,你就麻烦了。如果你不支持一行,并且缩进在其他人的机器上显示不一样…你有麻烦了。

    所以,问题是:这是一个错误的或不合理的标准有充分的理由吗?有人对此进行了一些讨论,但没有人能比“感觉很难看”更好地反驳我。

    21 回复  |  直到 15 年前
        1
  •  21
  •   om252345    15 年前

    我将其强制执行到某一点上,但if语句的计算结果要么返回要么继续循环则有一些小的异常。

    所以,按照我的标准,这是正确的:

    if(true) continue;
    

    像这样

    if(true) return;
    

    但是规则是要么返回,要么继续,并且都在同一行上。否则,一切都要用大括号。

    这种推理不仅是为了有一种标准的方式来做,而且是为了避免你提到的评论问题。

        2
  •  22
  •   Adam Bowen    15 年前

    我能提供的最好的反驳理由是,空间占用的额外行减少了一次可以看到的代码量,并且一次可以看到的代码量是发现错误的容易程度的一个重要因素。我同意你给出的包括括号的原因,但是在C++的很多年里,我只能想到一个结果,当我犯了一个错误的时候,它在一个我没有足够的理由跳过括号的地方。不幸的是,我不能告诉你看到这些额外的代码行是否有助于实践。

    我可能更偏向于这一点,因为我喜欢在同一缩进级别上匹配大括号的对称性(以及所包含语句的隐含分组作为一个执行块),这意味着添加大括号 全部的 时间给项目增加了许多线条。

        3
  •  11
  •   Mike DeSimone    15 年前

    我认为这条规则太过分了。严苛的标准并不能造就优秀的程序员,它们只是降低了一个懒汉将导致混乱的可能性。

    您给出的示例是有效的,但它们比强制使用大括号有更好的解决方案:

    当你一句话都没说出来,然后有人说出来的时候,你就麻烦了。

    有两种做法可以更好地解决这一问题,请选择一种:

    1)评论 if ,请 while 等。在一个衬里和一个衬里之前。即对待

    if(foo)
        bar();
    

    与任何其他多行语句(例如具有多行的赋值,或多行函数调用)一样:

    //if(foo)
    //    bar();
    

    2)前缀 // 用一个 ; :

    if(foo)
    ;//    bar();
    

    如果你不支持一行,并且缩进在其他人的机器上显示不一样…你有麻烦了。

    不,你不是;代码的工作原理是一样的,但很难阅读。修复压痕。选择标签或空格,并坚持使用它们。 不要混用制表符和空格来缩进。 许多文本编辑器会自动为您修复此问题。

    编写一些python代码。这样至少可以改善一些不良的压痕习惯。

    此外,结构如 } else { 在我看来像是一个打领带的Nethack版本。

    这是一个错误的或不合理的标准有充分的理由吗?有人对此进行了一些讨论,但没有人能比“感觉很难看”更好地反驳我。

    冗余大括号(和括号)是视觉混乱。视觉混乱使代码难以读取。代码越难阅读,隐藏错误就越容易。

    int x = 0;
    while(x < 10);
    {
        printf("Count: %d\n", ++x);
    }
    

    强制使用大括号无助于在上面的代码中找到错误。

    另外,我是“每一条规则都应该说明原因”学校的订阅者,或者达赖喇嘛所说的“知道规则,这样你就可以适当地打破它们。”

        4
  •  9
  •   Jeffrey Hines    15 年前

    我还没有让任何人想出一个不总是使用大括号的好理由。

    好处远远超过了我听过的任何“感觉很难看”的理由。

    编码标准的存在使代码更容易阅读和减少错误。

    这是一个真正有回报的标准。

        5
  •  5
  •   BryanD    15 年前

    我发现很难与减少错误和提高代码可读性的编码标准争论。一开始可能会让一些人觉得难看,但我认为这是一个完全有效的实施规则。

        6
  •  5
  •   Will Eddins    15 年前

    我站在支撑应根据压痕匹配的地面上。

    // This is right.
    if (foo) 
    {
        // bar
    }
    else 
    {
        // baz
    }
    
    while (things) 
    {
        // stuff
    }
    

    至于您的两个示例,我认为您的可读性稍差,因为查找匹配的右括号可能比较困难,但在缩进不正确的情况下可读性更高,同时允许更容易插入逻辑。没什么大不了的。

    即使缩进不正确,if语句也将执行下一个命令,不管它是否在下一行。不将这两个命令放在同一行的唯一原因是调试器支持。

        7
  •  4
  •   jball    15 年前

    我看到的一个很大的优势是,在有支撑的条件和循环中添加更多语句更容易,并且在开始时创建支撑不需要额外的击键。

        8
  •  4
  •   Matthew Groves    15 年前

    我个人的规则是,如果是一个非常短的“如果”,那么把它全部放在一行上:

    if(!something) doSomethingElse();
    

    一般情况下,只有在连续出现大量这样的假设时,我才使用这个。

    if(something == a) doSomething(a);
    if(something == b) doSomething(b);
    if(something == b) doSomething(c);
    

    不过,这种情况并不经常出现,否则,我总是使用大括号。

        9
  •  4
  •   seh Alexei    15 年前

    目前,我和一个按照这个标准生活的团队合作,尽管我抵制它,但为了统一起见,我还是遵守了这个标准。

    我反对的原因与我反对禁止使用例外、模板或宏的团队的原因相同: 如果您选择使用一种语言,请使用整个语言。 如果括号在C和C++和Java中是可选的,按惯例对它们进行约束会显示出对语言本身的一些恐惧。

    我理解其他答案中描述的危险,我理解对统一的渴望,但我不同情 语言子集 除非有严格的规定 技术原因 例如,对于某些不适应模板的环境,唯一的编译器,或与C代码的交互,排除了广泛使用异常。

    我一天中的大部分时间都是审查初级程序员提交的更改,而出现的常见问题与括号位置或语句结束在错误位置无关。危险被夸大了。我宁愿把时间花在更多的物质问题上,而不是寻找编译器乐意接受的违反规则的地方。

        10
  •  4
  •   Jason Williams    15 年前

    一组程序员能够很好地遵循编码标准的唯一方法是将规则的数量保持在最低限度。

    平衡收益和成本(每一个额外的规则都会混淆和混淆程序员,在某个阈值之后,实际上会减少程序员遵循任何规则的机会)

    因此,要制定编码标准:

    • 确保你能用清楚的证据证明每一条规则都比其他规则更好。

    • 看看这个规则的替代品——它真的需要吗?如果您的所有程序员都使用空白(空行和缩进),那么if语句非常容易阅读,而且即使是新手程序员也无法将“if”中的语句误认为是独立的语句。如果您得到了很多与if作用域相关的错误,那么根本原因可能是您的whitepsace/indentation样式不好,这使得代码不必要地难以读取。

    • 根据规则对代码质量的可测量影响来确定规则的优先级。通过实施规则可以避免多少错误(例如,“始终检查空值”、“始终使用断言验证参数”、“始终编写单元测试”和“即使不需要,也始终添加一些大括号”)。以前的规则每年可以为您节省数千个错误。大括号规则可能会为您节省一个。也许吧。

    • 遵守最有效的规则,丢弃谷壳。颖壳是一个最低限度的,任何规则,将花费你更多的实施比任何错误,可能会发生忽略规则。但是,如果您有超过30个关键规则,那么您的程序员可能会忽略其中的许多规则,而您的良好意图也将化为乌有。

    • 如果任何程序员在不阅读代码的情况下对代码的随机位进行注释,则将其激发:—)

    另外,我对支撑的立场是:如果“if”语句或其内容都是一行,那么可以省略支撑。这意味着,如果您有一个包含一行注释和一行代码的if,那么内容需要两行,因此需要大括号。如果if条件跨越两行(即使内容是单行),则需要大括号。这意味着您只需在一些琐碎、简单、易读的案例中省略大括号,而这些案例在实践中从未犯过错误。(当语句为空时,我不使用大括号,但我总是在注释中明确指出它是空的,并且故意这样做。但这与另一个主题有着不同的界限:在代码中要明确,这样读者就知道你的意思是一个范围是空的,而不是电话铃响,而你忘了完成代码)

        11
  •  3
  •   ennuikiller    15 年前

    许多语言都有这样一个语法行程序(我特别考虑Perl)来处理这种“丑陋”。比如:

    if (foo)     
    //bar
    else     
    //baz
    

    可以使用三元运算符编写为三元:

    foo ? bar : baz
    

    while (something is true)
    {
    blah 
    }
    

    可以写为:

    blah while(something is true)
    

    然而,在没有这种“糖”的语言中,我肯定会包括大括号。正如您所说,它可以防止不必要的bug侵入,并使程序员的意图更加清晰。

        12
  •  3
  •   Nemanja Trifunovic    15 年前

    我并不是说这是不合理的,但是在用类C语言编写代码的15多年中,我没有一个遗漏大括号的问题。在理论上,评论一个分支听起来像是一个真正的问题——我只是从未在实践中看到过它的发生。

        13
  •  3
  •   Josh Kelley    15 年前

    始终使用大括号的另一个优点是,它使搜索和替换以及类似的自动化操作更加容易。

    例如:假设我注意到 functionB 通常在 functionA ,使用类似的参数模式,因此我希望将复制的代码重构为新的 combined_function . 如果没有足够强大的重构工具,regex可以很容易地处理这个重构。( ^\s+functionA.*?;\n\s+functionB.*?; )但是,如果没有大括号,简单的regex方法可能会失败:

    if (x)
      functionA(x);
    else
      functionA(y);
    functionB();
    

    将成为

    if (x)
      functionA(x);
    else
      combined_function(y);
    

    更复杂的regex在这个特定的情况下可以工作,但是我发现能够使用基于regex的搜索和替换、一次性Perl脚本和类似的自动代码维护非常方便,所以我更喜欢一种不会使其变得不必要复杂的编码风格。

        14
  •  3
  •   rlbond    15 年前

    我不同意你的论点。就我个人而言,我不知道有谁曾经“意外地”在 if . 我会理解的 嵌套的 如果 声明应该有大括号以避免挂起其他语句,但正如我看到的那样,由于担心imo放错了位置,您强制使用了一种样式。

        15
  •  1
  •   Sam Harwell    15 年前

    以下是我过去一直遵守的不成文的规则。我相信它提供了可读性而不牺牲正确性。它基于这样一种信念:在相当多的情况下,短格式比长格式更易于阅读。

    • 如果 任何 方块 if/else if/else 语句有多行。注释计数,这意味着条件中任何地方的注释都意味着条件get大括号的所有部分。
    • 在下列情况下可选择使用大括号: 全部的 语句块正好是一行。
    • 不要将条件语句与条件放在同一行上。if语句后的行总是有条件地执行。
    • 如果条件语句本身执行了必要的操作,则表单将为:

      for (init; term; totalCount++)
      {
          // Intentionally left blank
      }
      

    当您只需说以下内容时,无需以详细的方式对其进行标准化:

    不要以牺牲可读性为代价而省略大括号。如果有疑问,请选择使用大括号。

        16
  •  1
  •   Ray    15 年前

    我认为大括号的重要之处在于它们非常明确地表达了程序员的意图。你不必从缩进中推断出意图。

    这就是说,我喜欢古斯建议的单行返回和继续。它的意图是显而易见的,而且更清晰,更容易阅读。

        17
  •  1
  •   vrv    15 年前

    如果您有时间通读所有这些内容,那么您有时间添加额外的大括号。

        18
  •  0
  •   John    15 年前

    为了可维护性,我更喜欢在单行条件中添加大括号,但是我可以看到没有大括号的情况下是如何变得更干净的。这并不困扰我,但有些人可能会被额外的视觉噪音关掉。

    我也不能提出更好的反驳。对不起的!;)

        19
  •  0
  •   Bob Cross n8wrl    15 年前

    对于类似的事情,我建议您为您的IDE的自动格式设置一个配置模板。然后,每当您的用户点击alt-shift-f(或者您选择的IDE中的任何按键),就会自动添加大括号。然后对每个人说:“去改变你的字体颜色,PMD设置或其他。不过,请不要更改缩进或自动大括号规则。”

    这就利用了我们可用的工具,以避免争论一些真正不值得用在氧气上的东西。

        20
  •  0
  •   Partial    15 年前

    依靠 语言 对于单行条件语句或循环语句,使用大括号不是必需的。实际上,我会删除它们以减少代码行数。

    C++:

    版本1:

    class InvalidOperation{};
    
    //...
    Divide(10, 0);
    //...
    Divide(int a, in b)
    {
       if(b == 0 ) throw InvalidOperation();
       return a/b;
    }
    

    版本2:

    class InvalidOperation{};
    
    //...
    Divide(10, 0);
    //...
    Divide(int a, in b)
    {
       if(b == 0 )
       { 
          throw InvalidOperation();
       }
       return a/b;
    }
    

    C:

    版本1:

    foreach(string s in myList)
       Console.WriteLine(s);
    

    版本2:

    foreach(string s in myList)
    {
       Console.WriteLine(s);
    }
    

    根据您的观点,版本1或版本2将更易于阅读。答案是 主观的 .

        21
  •  0
  •   pestilence669    15 年前

    真的。 没有人 意识到 dangling else problem ?这基本上是 这个 总是使用大括号的原因。

    简而言之,您可以对else语句使用令人讨厌的模糊逻辑,尤其是当它们被嵌套时。不同的编译器以自己的方式解决歧义。如果你不知道自己在做什么的话,去掉牙套可能是个大问题。

    美学和可读性与此无关。