使用没有花括号的if语句是不好的做法吗?

jer*_*ear 115 if-statement coding-style curly-braces

我见过这样的代码:

if(statement)
    do this;
else
    do this;
Run Code Online (Sandbox Code Playgroud)

我不喜欢这样,我认为这更清洁,更具可读性

if(statement){
    do this;
}else{
    do this;
}
Run Code Online (Sandbox Code Playgroud)

这只是一个偏好问题,还是会推荐一种方式?

cle*_*lee 195

第一个版本的问题是,如果你返回并在if或else子句中添加第二个语句而不记得添加花括号,那么你的代码将会以意想不到的方式破解.

可维护性,使用第二种形式总是更聪明.

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

  • 进一步的证据错误可以(并且确实)发生:https://www.imperialviolet.org/2014/02/22/applebug.html (16认同)
  • 并且您应该始终编写可维护性代码.毕竟,我很确定编译器不关心你使用哪种形式.然而,如果你因为愚蠢的花括号错误而引入了一个bug,那么你的同事可能会很开心. (15认同)
  • 或者您可以使用不使用括号代替代码块的语言... (12认同)
  • @ lins314159 - 不,我的意思是像python.因为我在这方面是沙文主义的. (9认同)
  • 声称SSL错误是支持大括号的论据是不诚实的.开发人员不打算写"if(...){goto L; 转到L; 但是忘记了牙箍.纯粹巧合的是``if(...){goto L; 转到L; 碰巧不是一个安全漏洞,因为它仍然是一个bug(只是没有安全隐患).在另一个例子中,事情可能会朝着相反的方向发展,无支撑代码可能会意外安全.在第三个例子中,无支撑代码最初是无错误的,开发人员在添加大括号时会引入拼写错误. (8认同)
  • 吕克:当然,这很简单,但也很容易忘记,如果你忘记了,那就太疯狂了,难以调试.保存一些角色真的值得潜在的头痛吗?我们大多数人似乎都认为答案是"不". (4认同)
  • Pascal:尽管编程错误,如果代码意外安全,真可惜!如果你总是使用支架,那么在"添加"它们时就不会有任何意外. (4认同)
  • 对“象牙塔假说废话”表示赞成(+1) (3认同)
  • @clee我知道这是一个3岁的线程,但我偶然发现了这个帖子并且忍不住要阅读你关于添加大括号的评论是"容易"忘记的.这不容易忘记,因为如果您使用适当的工具编写代码,这些工具会为您添加这些括号.即使您没有使用正确的工具,如果您碰巧使用的是使用大括号的语言(尽管我喜欢python),但在编写`if`语句时,它应该在您的肌肉记忆中,并且如果不是,那么你应该努力. (3认同)
  • 我不同意,当您需要添加代码时,请添加括号。阅读和实现相当简单。 (2认同)
  • Apple Bug为+1 (2认同)
  • 这篇文章的作者谈到了苹果虫的结论:"也许编码风格通过允许没有括号的ifs来实现这一点,但是也可以使用括号进行不正确的缩进,**这对我来说似乎并不十分令人信服**".我同意. (2认同)
  • @IlikeBeansTacos,按照踢死马的伟大传统……伟大的工具肯定可以提供帮助,但并不是每个人都使用它们。C 有很多方式让你搬起石头砸自己的脚,我认为这就是其中之一。仅仅因为该语言允许您执行某些操作(例如在 if/else 语句中省略大括号)并不意味着这是一个好主意。(另外,我不喜欢Python。) (2认同)

doy*_*nax 96

遗漏语句块的一个问题是其他模糊性.这是C语言的语言忽略缩进,所以没有办法分离这个:

if(one)
    if(two)
        foo();
    else
        bar();
Run Code Online (Sandbox Code Playgroud)

由此:

if(one)
    if(two)
        foo();
else
    bar();
Run Code Online (Sandbox Code Playgroud)

  • 这是一个比最顶层答案中提到的问题(添加第二个语句)更严重的问题. (5认同)
  • 事实上,这个答案实际上让我从愤世嫉俗地阅读这些答案到稍微担心我实际上可能犯了这个错误。 (5认同)
  • “歧义”是错误的术语。解析器将如何看待这一点没有任何歧义:`else` 贪婪地绑定到最近的、最里面的 `if`。问题出现在 C 或类似语言被那些不知道这一点、不考虑它或还没有喝足够咖啡的人编码的地方——所以他们编写了他们认为可以做一件事的代码,但是语言规范说解析器必须做其他事情,这可能非常不同。是的,即使语法将它们标记为理论上“不必要”,这是另一个支持始终包含大括号的坚如磐石的论点。 (4认同)
  • 如果有人想知道我是哪个C实际上解释它,我用GCC做的测试以第一种方式解释这个代码.http://tpcg.io/NIYeqx (2认同)

Mat*_*chu 33

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

if(true) do_something();
Run Code Online (Sandbox Code Playgroud)

如果有一个else子句,或者我想要执行的代码true是非常长的,那么就一直支持:

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

if(false) {
    do_something();
} else {
    do_something_else();
}
Run Code Online (Sandbox Code Playgroud)

归根结底,它归结为风格和可读性的主观问题.然而,一般的编程世界几乎分为两个派对(对于使用大括号的语言):要么一直使用它们而没有例外,要么一直使用它们,例外.我是后一组的一员.

  • 任何数量的括号都不会使维护者无法使用他的大脑.我支持"没有括号,如果它适合一行"的想法,因为,对我来说,这样的if只是_ternary的一个版本if operator_其中一个不需要在"after:"部分做任何事情.三元.为什么有人会在第__句中引入括号? (6认同)
  • 虽然,编写`if(true){do_something(); 为什么有机会让另一个程序员在路上引入一个严重的错误(查找Apple的"goto fail"总ssl代码搞砸了). (4认同)

Pen*_*m10 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;
}
Run Code Online (Sandbox Code Playgroud)

  • 我支持这种风格.大多数人从左到右阅读代码,这有点使我们的眼睛锚定在屏幕的左边缘.它有助于在视觉上将代码分离并提取到逻辑步骤块. (14认同)
  • 我总是喜欢这种风格.更容易找到相应的右括号.这需要很大的空间吗?使用较小的字体. (6认同)
  • 这是一个完全主观的风格问题,我个人不喜欢仅支撑线的冗余.但是,嘿. (5认同)
  • 当大括号在不同的行上时,我总是发现通过代码"扫描"更容易.这适用于一切; 类,方法,if-和while-语句等等.从来没有喜欢在同一条线上拥有第一个支架...... (4认同)
  • 空白很便宜,特别是当你有一个具有代码折叠能力的IDE时. (2认同)
  • 我知道这已经晚了,但@Svish,要小心返回语句和javascript :),所有突然的花括号都需要在同一行 (2认同)

Mat*_*hop 8

从第一刻开始正确使用大括号应该有助于防止您不得不调试它:

if (statement)
     do this;
else
     do this;
     do that;
Run Code Online (Sandbox Code Playgroud)

  • 因此,当你点击`;`:)时,有一个IDE可以纠正缩进 (2认同)

Mar*_*son 7

我遵循的"规则"是这样的:

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

if($test)
{
    doSomething();
}
Run Code Online (Sandbox Code Playgroud)

这是因为我觉得你需要明确在什么条件下调用哪些函数以及程序流程在哪里.让程序员准确理解调用哪些函数以及在这种情况下设置哪些变量对于帮助他们准确理解程序正在执行的操作非常重要.

如果"if"语句正在测试以便停止执行某些操作(循环或函数中的IE流控制),请使用单行.

if($test) continue;
if($test) break;
if($test) return;
Run Code Online (Sandbox Code Playgroud)

在这种情况下,对程序员来说重要的是快速发现不希望代码运行的异常情况,这些都是在$ test中,而不是在执行块中.


lee*_*ers 6

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

if (someFlag) {
 someVar= 'someVal1';
} else {
 someVar= 'someVal2';
}
Run Code Online (Sandbox Code Playgroud)

看起来像这样更好:

someVar= someFlag ? 'someVal1' : 'someVal2';
Run Code Online (Sandbox Code Playgroud)

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