为什么省略花括号被认为是一种不好的做法?

188

为什么每个人都告诉我像这样编写代码是一种不良实践呢?

if (foo)
    Bar();

//or

for(int i = 0 i < count; i++)
    Bar(i);

我认为省略花括号的最大优点是,有时候使用花括号会造成代码行数翻倍。例如,下面是用C#绘制标签发光效果的一些代码:

using (Brush br = new SolidBrush(Color.FromArgb(15, GlowColor)))
{
    for (int x = 0; x <= GlowAmount; x++)
    {
        for (int y = 0; y <= GlowAmount; y++)
        {
            g.DrawString(Text, this.Font, br, new Point(IconOffset + x, y));
        }
     }
 }
 //versus
using (Brush br = new SolidBrush(Color.FromArgb(15, GlowColor)))
    for (int x = 0; x <= GlowAmount; x++)
        for (int y = 0; y <= GlowAmount; y++)
            g.DrawString(Text, this.Font, br, new Point(IconOffset + x, y));

您还可以获得链接 usings 的附加好处,而无需缩进数百万次。

using (Graphics g = Graphics.FromImage(bmp))
{
    using (Brush brush = new SolidBrush(backgroundColor))
    {
        using (Pen pen = new Pen(Color.FromArgb(penColor)))
        {
            //do lots of work
        }
    }
 }
//versus
using (Graphics g = Graphics.FromImage(bmp))
using (Brush brush = new SolidBrush(backgroundColor))
using (Pen pen = new Pen(Color.FromArgb(penColor)))
{
    //do lots of work
}

花括号最常见的使用是为了维护编程,并避免在原始if语句和其预期结果之间插入代码带来的问题:

if (foo)
    Bar();
    Biz();

问题:

  1. 想使用语言提供的更紧凑的语法有错吗?设计这些语言的人很聪明,我无法想象他们会加入一种总是不好使用的特性。
  2. 我们应该还是不应该编写代码让最低公共分母能够理解并且没有问题地与之工作?
  3. 还有其他的论点我错过了吗?

8
我同意你的看法。省略它们。句号。 - Andrei Rînea
77
谁会在2010年关心某个东西有多少行啊?现在的显示器都很宽、很便宜,而且分辨率很高!我的显示器是2048 x 1152,而且我有两个!可读性比节省2个垂直线更重要,因为你很容易引入难以发现的细微错误。 - user177800
56
显示器宽而便宜,但不高也不便宜。垂直空间比水平空间更为紧缺。 - Adam Ruth
38
把它们横过来 :) - Zachary Yates
17
为了避免像苹果在2014年2月发现的SSL漏洞那样出糗,哈哈。 - learnvst
显示剩余15条评论
52个回答

3

他们之所以告诉你这个,是因为他们仍在使用古老的或者通用的(非语言感知的)源代码编辑器。 如果你使用自动缩进的编辑器,你就不会犯那些本可以通过一直使用大括号避免的错误。


2
  1. 空格是免费的。
  2. 依赖缩进来保证未来的可读性意味着依赖标签设置,这不是一个好主意。你曾经处理过没有受到修订控制的十年前的代码吗?
  3. 我的经验是,你通过不打大括号节省的任何时间都比我花费的额外时间更多,因为我需要弄清楚你的意思。

2
一种结合了两者优点的替代方法是:
if(foo)
   {DoSomething();}

这样做可以避免在注释掉该行或在其下方添加另一行时出现混淆。
此外,我们使用MISRA-C作为编码标准,该标准要求所有类似于此的结构都必须在任何情况下都使用大括号。

1

我曾经也讨厌大括号。直到有一天我发现了它们的用处。我在不同的平台上工作,将应用程序从一个平台移植到另一个平台(总共使用6个平台)。在UNIX上,如果你安装了vim,那么你可以通过按下“Shift + 5”轻松跳转到代码块的结尾或开头。这些代码块通常是if/else块或循环。

因此,如果我在vim上查看Rampion的问题,我会完全迷失,并需要一段时间才能完全理解代码。


1

因为 StyleCop 这么说。


ReSharper建议删除大括号。无论哪种方式都可以,但我想使用将来更容易阅读的方式。 - Rich

1

如果您的维护程序员在将逻辑添加到应用程序时忘记添加花括号,则会发生以下情况:

if(foo)
bar();
bar(delete);

与其

if(foo) {
bar();
}
 bar(delete);

那个观点在问题中已经提出。 - Mike Scott
Mike:那么它不应该被关闭为“不是一个真正的问题”吗?其他人也提出了这个观点,你也给他们投了反对票吗?最终,这就是为什么这是一个不好的做法的实际答案。 - George Stocker
我认为他正在努力获得更多的徽章。 - Elie
1
那个缩进太糟糕了。 - recursive

1
将左括号与上一条语句放在同一行:
if ( any ) {
    DoSomething();
}

  • 如果你觉得这太大了,你可以把它写成一行:
  • if ( any ) { DoSomething(); }
    

    如果你觉得一行代码不太易读,可以将其分成两行:

    if ( any ) {
        DoSomething(); }
    if ( any )
        { DoSomething(); }
    
    • 将来有人需要将一个语句改为多个语句。如果没有括号,这种更改会更加复杂。是的,只有一点点,但最好预防错误。而且编写括号非常容易且经济实惠。

    闭合括号应该始终位于块的级别,而不是在最后一行的末尾。 - recursive
    这比不使用括号还要糟糕。 - FINDarkside

    1

    我认为省略大括号并不总是一种不好的做法,但是否应该允许以及在什么情况下允许必须在团队中达成共识。

    我觉得这样很容易阅读:

    if (foo)
        bar();
    

    还有这个:

    if (foo)
        bar()
    else
        snafu();
    

    如果在这些代码中添加了一行额外的内容:-
    if (foo)
        bar();
        snafu();
    

    这看起来完全不对,有一段缩进的代码块,但没有括号。

    对于for循环也是类似的情况。然而,当我开始嵌套时:-

    if (foo)
        if (bar)
            snafu()
    

    现在我遇到了麻烦,看起来像一堆语句。个人而言,我只会跳过一个级别的大括号使用,如果更深层次的话,我会让外部代码使用大括号:

    if (foo) {
       if (bar)
           snafu()
    }
    

    当我正在输入时,我看到答案从1跳到17,显然这将是一个充满感情的问题(我建议您将主观性添加到标签列表中(我的能力已经消失了,出了什么问题?))。
    最重要的是确保团队对是否以及如何接受并坚持自己的意见达成一致。

    1
    尝试使用 if (foo && bar) snafu()。C#支持短路 :) - Brian

    1

    我认为这一切都归结于个人偏好和可读性。通常添加花括号会使您的代码更易读,因为它增加了实际代码行之间的额外空间。此外,请考虑以下示例(故意未缩进):

    if (condition1)
    if (condition2)
    doSomething();
    else
    doSomethingElse();
    

    当condition1为真而condition2为假时,doSomethingElse会被调用吗?还是当condition1为假时?快速添加花括号可以解决这个可读性问题并避免混淆。


    0

    这是一个权衡,短代码(更易读)与更安全的代码(更少出错)之间的权衡。

    我的两分钱:

    1. 有一个原因造成了这个规则。它是由无数程序员通过长时间的工作而开发出来的,他们的工作时间延伸到夜晚或第二天早上,试图修复由于小疏忽而导致的错误。
    2. 你必须自己决定这种权衡是否值得。
    3. 根据我的经验,它是值得的,我是那些在深夜工作以找到恶意 bug 原因的无数程序员之一。原因是我太懒了。

    1
    在第一点中提到的无数程序员,他们是我们应该追随的行业领袖,还是普通的低端程序员? - Bob
    他们是我们的前辈,那些在古代为我们今天所熟知的编程技术奠定基础的神话般的人物。我们将永远感激他们。他们所做的众多重要工作之一就是废除了被称为GOTO的邪恶。 - Treb

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接