维护方面,在不进行大括号干预的情况下“其他时间”是否被认为安全?


26

是否在else while不使用大括号的情况下将其视为“安全”的维护方法?

编写if-else没有括号的代码,如下所示...

if (blah)
    foo();
else
    bar();

...带有风险,因为缺少花括号,很容易在不经意间更改代码的含义。

但是,下面是否也有风险?

if (blah)
{
    ...
}
else while (!bloop())
{
    bar();
}

还是else while不使用大括号将其视为“安全”的?


20
对我来说else while看起来很邪恶。我会用else { while (condition) { ... } }
约阿希姆·绍尔

7
我认为对于一个正确的答案来说太主观了。我不愿意这样做,因为我不希望在那里出现循环,并且我认为我不希望增加可读性。
johannes 2012年

7
我想提取方法的同时,东西
蚊蚋

12
老实说,这让我感到毛骨悚然。if仅被评估一次,但while表示一个循环,因此将两者连接都会给我一种毫无根据的感觉,即if该循环是循环的一部分...
user281377 2012年

4
如果要在else子句中执行while 做更多的事情,该怎么办?请只用大括号。
卡洛斯·坎德罗斯

Answers:


57

那让我想起了这段代码:

if ( ... ) try {
..
} catch (Exception e) {
..
} else {
...
}

每次您将两种类型的块组合在一起,忘记花括号而不增加缩进量时,就会创建很难理解和维护的代码。


18
好例子。多么可怕的写法。
Leo

4
哇,这个答案简直令人信服!
Mehrdad

您可以轻松地设置现代IDE,以便在保存时自动格式化代码-包括插入花括号和更正缩进。因此,这只是争论的一半。适当地缩进后,无论是否有花括号,对可读性都不会造成问题。
汉斯·彼得·斯托尔2013年

55

也许是因为我使用杰克逊实体结构图方法学习了我的交易(追溯到何时),但是我赞成这样的观点,即在或之后唯一正确的无括号项是后续项(即允许阶梯)ifelseifelse if

其他(无双关语)可能会引起误解和/或维护问题。这是行动方案想法“不安全”的核心方面。

我也会非常谨慎地while()else- 包含在与-相同的行上,无论是否支撑。这对我来说并不正确……缺少任何额外的缩进遮罩,表明它是该else子句。缺乏明确性会造成误解(见上文)。

因此,在该示例中,我将强烈建议/推荐(并在我的团队中坚持):

if ( blah )
{
    ...
}
else
{
    while ( !bloop() )
    {
        bar();
    }
}

当然,我也希望看到适当的评论。

-编辑-

最近,苹果公司因维护不力而导致了SSL漏洞-在没有支撑的单行中增加了第二行。因此,让我们接受这样的想法,即无括号的单行可以吗?


2
我同意是否是遵循其他术语的唯一正确术语。如果有一个else whileI,我可能甚至不会注意到代码的快速浏览中会有一个循环,尤其是如果if满足了我正在寻找的条件。
德雷克·克拉里斯(Decake Clarris)2012年

3
这很有趣。每个人都说,如果所有内容都用大括号括起来,则更容易阅读。我发现事实恰恰相反。如果仅是一条语句,将其保留在大括号内将使其更易于阅读。减少混乱。可能只是因为我一直都这样做。
杰夫·戴维斯

2
@JeffDavis,这很不错。“易于阅读”是无用圣战的典型邀请。我更喜欢花括号,但这并不是因为不相关的“易读”垃圾(例如,对我来说是完全相反的),而是因为在进一步的代码维护中很难打破。顺便说一下,OP在他们的问题中拼写得更好:else while没有大括号的情况下,是否被认为是“安全的”
蚊蚋

@JeffDavis-我知道这个线程已经使用了两年了,但是苹果最近发现了为什么不使用括号不是一个好主意andrewbanks.com/…–
安德鲁(

@Andrew顺便说一句,Apple的Swift语言现在明确禁止单线流控制。该错误可能是这样做的原因之一。
苏珊(Sulthan)2016年

6

我一直被教导要把所有东西都放在括号内,缩进和评论。我认为阅读和发现错误要容易得多。我个人认为模块化是关键,所以我总是会这样写代码:

    if(blah)
    {
     ....
    }
    else
    {
       while(!bloop()
       {
        bar;
       }
    }

6

我会提取方法并使其

if ( blah )
{
    ...
}
else
{
   newMethod();
}

请参阅“ 重构目录”站点上解释的“提取方法”方法:

您有一个可以组合在一起的代码片段。

将片段转换为方法,其名称说明该方法的用途。

void printOwing() {
    printBanner();

    //print details
    System.out.println ("name:    " + _name);
    System.out.println ("amount    " + getOutstanding());
}

                                                                                                         http://www.refactoring.com/catalog/arrow.gif

void printOwing() {
    printBanner();
    printDetails(getOutstanding());
}

void printDetails (double outstanding) {
    System.out.println ("name:    " + _name);
    System.out.println ("amount    " + outstanding);
}

取决于...例如,如果while循环使用了函数级别的数据,则您现在必须将更多数据添加到模块(或类,如果使用C ++)级别。而且,如果只是一小段代码,您就会陷入琐碎的方法中。但是有时候,我会视情况而同意。
Andrew

1
+1 Smart C ++编译器可以内联函数。在.Net环境中,由于JIT,小功能更好。
工作

4

我认为这是一种不良的编码习惯。有时,它工作得很好,并且您在编译和运行代码时不会遇到任何问题。在其他时候,它可能会导致严重的错误,您最终将花费数小时来修复该错误。

始终建议对代码进行模块化。如果必须在其他部分放入while循环,则将其放在一个块中,以便其他人在执行代码时可以轻松理解逻辑。

if ( blah )
{
    ...
}
else
{
    while ( !bloop() )
    {
        bar();
    }
}

将代码放在块中是一个好习惯。它还使它更易于理解和调试。


4

如果它像这样简单就可以了,尽管我个人不喜欢它,我的偏好是即使在最简单的if / else代码块中也要使用花括号。对我来说只是比较整齐。

但是,当您嵌套if / else循环一些带花括号而另一些不带花括号时,这会变得凌乱。所有义大利面中间都有While循环!我使用过的代码很糟糕,调试和理解都是噩梦。从第一点开始,当它保持简单并且您对此感到满意时就很好了,但是随后其他程序员开始为它添加内容,可能在while循环中添加了其他内容。如果一开始就把它写得整洁,那么发生这种情况的可能性就较小。

关键是要弄清楚事情,以便其他程序员可以一目了然地了解是非。编写代码,以使模式看起来正确并且不会震撼。

另一方面,也许我可以看到有人声称在某些情况下,这很好理解。如果我有资源,则在等待某些东西的同时进行其他处理。即便如此,在else块中嵌套while循环仍然没有区别。


3

好吧,尽管每个人都在争论使用牙套并且似乎很喜欢它们,但我实际上更喜欢相反的说法。我只在需要时才使用花括号,因为我发现花括号更容易阅读和简洁。

if (...)
   foo();
else while(...)
   bar();

...我实际上发现此“ else while(...)”非常可读!它甚至听起来像是普通的英语!但是我想人们都会发现它很奇怪,因为至少可以说这很不寻常。

最后,尽管...大家知道,我们都倾向于用大括号使它防白痴。


3
在一些无辜的维护者更改else while(...) bar();为类似的内容之后,这将特别可读else while(...) foobar(); bar();:)
gnat 2012年

3
好吧,我会说这是一个非常愚蠢而危险的无辜维护者。我知道为避免愚蠢的错误而愚弄它的原则...但是走到现在仍然相当可悲。但是我知道我会得到这样的评论和反对。没问题。
dagnelies 2012年

2
“总是编码,就像维护您的代码的人是知道您的住所的暴力心理变态者一样。” (艾伦Braggins

1
好吧,一切都可以归结为您认为代码编写人员最愚蠢的水平。我认为,如果您的“维护者”被这四行代码弄糊涂了……那么您将面临一个巨大的问题。如果这是一种暴力心理,那么您有两个。;)
dagnelies 2012年

1
如果 -很好,我在上面引用的链接已扩展了以下引语的版本:程序员1:“此处有一个引人注目的内容-“始终以代码的形式,就像将要维护您代码的人是知道您住在哪里的暴力精神病患者”。 。程序员2 :(查看维护者)“您的意思是”好像”?
gnat 2012年

2

我总是戴上牙套,只是因为您可能会急着增加另一行,缩进去,忘记牙套并挠头。我将左括号放在同一行,但这没关系。我两种情况都最好有它们。

if(blah) {
    foo();
}
else {
    bar();
}

牙套的位置可能比宗教以外(或可能包括宗教)引发更多的争论!
安德鲁

同意 将编辑我的答案以强调其存在,而不是位置。
茨威托米尔·迪米特洛夫

2

花括号有什么问题,以至于很多人试图避免写这些花括号?

到底能else while解决什么问题?

括号既便宜又好用,并且使代码的意图清晰明了,而不是聪明机智。

引用Unix哲学:

清晰规则:清晰胜于聪明。

因为维护是如此重要且昂贵,所以编写程序就像把它们做的最重要的通信不是发送给执行它们的计算机,而是给将来将要阅读和维护源代码的人(包括您自己)。


1

没有错

if (blah)
    foo();
else
    bar();

就像没有错

if (blah) foo(); else bar();

在适当的情况下(您的情况可能会有所不同,但是当您有很多重复的代码时,最好使用特定样式-然后,每行的视图比样式缩进更为重要)

但是,如果您选择一种方法,请坚持下去-一致性至上。因此,您的第二个示例非常糟糕,因为if表达式的语句带有方括号,而while语句应位于else子句的方括号内,而不是在其外部。


另外,我之前也看过这段代码:

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

它是由编码标准纳粹本人(他坚持用括号括住所有内容)编写的。


1

可以将现代IDE轻松配置为重新格式化(包括删除或添加不必要的花括号)和/或在保存文件时重新缩进代码。因此,您的示例将自动看起来像

if (blah) {
  blub();
} else
  while (!bloop()) {
    bar();
  }

即使没有不必要的花括号,该凹痕也总是使嵌套易于看到。因此,如果您设法强制执行此类IDE设置,则不会有任何风险。

就我个人而言,我发现省略花括号和换行符的代码更具可读性,因为它避免了混乱:

if (blah) blub();
else while (!bloop()) bar();

但是,当然,许多开发人员很乐意为这样的事情永远争论不休。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.