使用不带花括号的if语句是不好的做法吗?[关闭]


130

我看过这样的代码:

if(statement)
    do this;
else
    do this;

但是,我认为这更具可读性:

if(statement){
    do this;
}else{
    do this;
}

既然这两种方法都起作用,那么这仅仅是使用偏好还是会推荐一种方法而不是另一种方法?



我认为这很糟糕,因为您开始依赖几乎从来没有完全一致的空格缩进。当他们不得不担心这类事情时,它使读者的思路偏离了轨道。
Sridhar Sarnobat,

Answers:


212

第一个版本的问题在于,如果您回过头向if或else子句添加第二条语句而又不记得要添加花括号,那么您的代码将以意想不到的有趣方式中断。

在可维护性方面,使用第二种形式总是更聪明。

编辑:内德在评论中指出了这一点,但我认为也值得链接到这里。这不仅是一些象牙塔的废话:https : //www.imperialviolet.org/2014/02/22/applebug.html


17
而且您应该始终编写可维护性代码。毕竟,我敢肯定编译器不会在乎您使用哪种形式。但是,如果您由于愚蠢的花括号错误而引入了错误,那么您的同事可能会更加谨慎。
Esteban Araya

12
或者您可以使用一种不对代码块使用方括号的语言...
Tor Valamo 2010年

10
@ lins314159-不,我的意思是像python。因为我在这方面是沙文主义的。
Tor Valamo

17
可能(并且确实)发生进一步的证明错误:imperialviolet.org/2014/02/22/applebug.html
2014年

8
声称SSL错误是支持大括号的说法是不合理的。这似乎不是开发人员打算写if (…) { goto L; goto L; }但忘记了花括号。``如果(...){转到L; 转到L; }`碰巧不是安全漏洞,因为它仍然是一个错误(不是一个有安全后果的错误)。在另一个示例中,事情可能朝着相反的方向发展,无括号的代码可能会意外地安全。在第三个示例中,无括号代码最初将是无错误的,并且开发人员将在添加括号时引入错字。
Pascal Cuoq 2014年

112

遗漏语句块的一个问题是else-歧义。那就是受C语言启发的语言会忽略缩进,因此无法将其分开:

if(one)
    if(two)
        foo();
    else
        bar();

由此:

if(one)
    if(two)
        foo();
else
    bar();

8
这比最上面的答案(添加第二条语句)中提到的问题要严重得多。

3
确实,这个答案实际上使我从愤世嫉俗地阅读这些答案,到有点担心我可能确实犯了这个错误。
忽略

2
如果其他人想知道我是C真正解释它的方式,那么我对GCC所做的测试将以第一种方式解释该代码。tpcg.io/NIYeqx
奥尔塔(

2
“模棱两可”是错误的术语。解析器如何看待这一点没有任何歧义:else绑定贪婪地绑定到最近的,最里面的if。问题出在不了解,不考虑或还没有喝咖啡的人正在使用C或类似语言编写代码时-他们编写了认为可以做一件事的代码,但是语言规范说解析器必须做其他事情,这可能会大不相同。是的,这是另一个坚如磐石的论点,主张即使语法在理论上将括号标记为“不必要的”,也要始终包含括号。
underscore_d

35

我的一般模式是,如果它适合一行,我会这样做:

if(true) do_something();

如果有一个else子句,或者如果我想执行的代码true长度很大,请一直将其括起来:

if(true) {
    do_something_and_pass_arguments_to_it(argument1, argument2, argument3);
}

if(false) {
    do_something();
} else {
    do_something_else();
}

最终,它归结为样式和可读性的主观问题。但是,一般的编程世界几乎分为两方(对于使用花括号的语言):要么一直无一例外地使用它们,要么一直无例外地使用它们。我属于后者。


4
尽管编写起来很容易,但是if(true){ do_something(); }为什么要趁这个机会让另一个程序员介绍一个严重的错误(查找Apple的“ goto fail”总ssl代码错误)。
克雷格

9
没有多少括号会使维护者摆脱使用大脑的负担。我支持“如果放在一行中就没有括号”的想法,因为对我来说,这样的if只是三元if运算符的一个版本,其中的操作符不需要在“ after:”部分中做任何事情三元。为何有人会在三元括号中引入括号呢?
Michal M

我完全不同意它最终是主观的,也不仅仅影响样式和可读性。作为浪费时间尝试调试问题的人,这是由于缺少块定界符(并且没有注意到它们的缺席)引起的,因为我不得不使用一种编码样式,在“不必要”时忽略了它们-并且他已经阅读了许多这样的编码风格很可能会引起可怕的错误-我认为这是一个非常客观,实际的问题。当然,使用强制性分隔符的样式,我们仍然可以忘记它们,但至少可以肯定,肌肉记忆使我们不太可能。
underscore_d

10

我正在使用所使用的IDE的代码格式化程序。可能有所不同,但是可以在“首选项/选项”中进行设置。

我喜欢这一个:

if (statement)
{
    // comment to denote in words the case
    do this;
    // keep this block simple, if more than 10-15 lines needed, I add a function for it
}
else
{
    do this;
}

5
这是一个完全主观的风格问题,我个人不喜欢仅括号行的冗余。可是
Matchu

14
我支持这种风格。大多数人从左到右阅读代码,这使我们的眼睛锚定在屏幕的左边缘。它有助于从视觉上分离代码并将其提取到逻辑步骤块中。
mloskot 2010年

6
我一直喜欢这种风格。查找对应的右括号要容易得多。那么需要很多空间吗?使用较小的字体。
2010年

4
当花括号位于单独的行时,我总是发现更容易“扫描”代码。这适用于一切;类,方法,if和while语句等。从来没有喜欢在同一行上有第一个支撑...
Svish 2010年

2
空格便宜,尤其是当您具有支持代码折叠的IDE时。
Moo 2010年

10

我遵循的“规则”是这样的:

如果“ if”语句正在测试以便执行某些操作(IE调用函数,配置变量等),请使用花括号。

if($test)
{
    doSomething();
}

这是因为我觉得您需要弄清楚在什么条件下正在调用什么函数以及程序的流向。让程序员确切地了解在这种情况下调用了哪些函数以及设置了哪些变量,对于帮助他们确切地了解您的程序在做什么很重要。

如果正在测试“ if”语句以停止执行某项操作(循环或函数中的IE流控制),请使用一行。

if($test) continue;
if($test) break;
if($test) return;

在这种情况下,对程序员来说重要的是迅速发现哪些异常情况是您不希望代码运行的,而所有这些情况都包含在$ test中,而不是在执行块中。


8

从一开始就拥有大括号,这将有助于防止您不得不调试以下内容:

if (statement)
     do this;
else
     do this;
     do that;

1
这似乎是公认的原理,但是(在这里扮演魔鬼的拥护者)难道没有一条额外的语法高亮规则可以解决这一问题,同时节省一行吗?
肯(Ken)

2
所以会有一个IDE可以在您点击时纠正缩进;:)
Sam Harwell 2010年

6

对于所有if语句甚至简单的语句都使用大括号。或者,重写一个简单的if语句以使用三元运算符:

if (someFlag) {
 someVar= 'someVal1';
} else {
 someVar= 'someVal2';
}

看起来像这样更好:

someVar= someFlag ? 'someVal1' : 'someVal2';

但是,如果您绝对确定if / else块中没有其他需要,请仅使用三元运算符!



2

根据我的经验,第一种形式的唯一(非常)轻微的优势是代码可读性,第二种形式增加了“噪音”。

但是,强烈建议使用第二种形式的现代IDE和代码自动生成(或自动完成)功能,这样您就不必花更多的时间键入花括号,并且可以避免一些最常见的错误。

有足够多的耗能虫子,人们只是不应该浪费大量时间而开门。

编写代码时要记住的最重要规则之一是一致性。无论是谁编写的,每一行代码都应以相同的方式编写。严谨防止错误“发生”;)

这与清楚明确地命名变量,方法,文件或正确缩进它们相同...

当我的学生接受这一事实时,他们就不再与自己的源代码作斗争,他们开始将编码视为一项非常有趣,刺激和创造性的活动。他们挑战自己的思想,而不是他们的神经!


2

这是一个优先事项。我个人使用这两种样式,如果我有把握地确定不再需要添加其他语句,则使用第一种样式,但如果可能,则使用第二种样式。由于您无法再向第一种样式添加语句,因此我听说有人建议不要使用它。但是,第二种方法的确增加了一行代码,如果您(或您的项目)使用这种编码风格,则第一种方法非常适合简单的if语句:

if(statement)
{
    do this;
}
else
{
    do this;
}

但是,我认为解决此问题的最佳方法是使用Python。使用基于空白的块结构,您没有两种不同的方法来创建if语句:您只有一种:

if statement:
    do this
else:
    do this

尽管确实有一个“问题”,您根本无法使用花括号,但您的确获得了好处,即第一种样式不再包含任何行,并且可以添加更多语句。


我自己认为Python处理if-else语句的方式非常丑陋,但我又不是Python程序员(至今)
helpermethod 2010年

1

我一直试图使我的代码标准,并看起来尽可能接近。这使得其他人在负责更新它时更容易阅读它。如果您执行第一个示例并在中间添加一行,它将失败。

无法运作:

如果(声明)这样做;还有这个; 否则这样做;


1

我个人使用第一种样式仅抛出异常或过早地从方法返回。就像函数开头的参数Checking一样,因为在这种情况下,很少要做一件事,而没有其他事情要做。

例:

if (argument == null)
    throw new ArgumentNullException("argument");

if (argument < 0)
    return false;

否则,我使用第二种样式。


1

我个人的喜好是混合使用空格和方括号,如下所示:

if( statement ) {

    // let's do this

} else {

    // well that sucks

}

我认为这看起来很干净,并且使我的代码非常易于阅读,最重要的是调试。


0

我同意大多数答案,因为最好在代码中明确使用大括号。我个人将采用一套编码标准,并确保团队中的每个人都知道并遵守。在我工作的地方,我们使用IDesign.net为.NET项目发布的编码标准。


0

我更喜欢大括号。但有时,三元运算符会有所帮助。

代替 :

int x = 0;
if (condition) {
    x = 30;
} else {
    x = 10;
}

一个人应该简单地做: int x = condition ? 30 : 20;

还要想象一个案例:

if (condition)
    x = 30;
else if (condition1)
    x = 10;
else if (condition2)
    x = 20;

如果放入花括号,那会更好。

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.