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

Java 为什么省略花括号被认为是一种不好的做法?,java,c#,c++,c,coding-style,Java,C#,C++,C,Coding Style,为什么每个人都告诉我这样写代码是一种糟糕的做法 if (foo) Bar(); //or for(int i = 0 i < count; i++) Bar(i); 大括号最常见的参数围绕维护编程,以及在原始if语句与其预期结果之间插入代码所导致的问题: if (foo) Bar(); Biz(); 问题: 想要使用该语言提供的更紧凑的语法是错误的吗?设计这些语言的人都很聪明,我无法想象他们会使用一个总是不好用的特性 我们是否应该或不应该编写代码

为什么每个人都告诉我这样写代码是一种糟糕的做法

if (foo)
    Bar();

//or

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

大括号最常见的参数围绕维护编程,以及在原始if语句与其预期结果之间插入代码所导致的问题:

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

问题:
  • 想要使用该语言提供的更紧凑的语法是错误的吗?设计这些语言的人都很聪明,我无法想象他们会使用一个总是不好用的特性
  • 我们是否应该或不应该编写代码,以便最低公分母能够理解并在使用它时没有问题
  • 我还遗漏了另一个论点吗

  • 假设您有一些代码:

    if (foo)
        bar();
    
    然后另一个人走了过来,补充道:

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

    根据它的书写方式,bar();现在是无条件执行的。通过包含花括号,可以防止这种意外错误。代码的编写方式应使此类错误难以或不可能发生。如果我在做代码检查时发现缺少大括号,尤其是跨多行的大括号,我会创建一个缺陷。在有正当理由的情况下,将其保留在一行,以使再次出现此类错误的机会保持在最低限度。

    总是有例外,但我反对仅在以下其中一种形式中省略大括号:


    否则,我不会有任何问题。

    事实上,唯一一次真正咬我的是在调试时,并注释掉了bar():

    除此之外,我倾向于使用:

    if(foo) bar();
    
    这就解决了上述问题


    编辑谢谢你澄清了这个问题,我同意,我们不应该编写最低公分母的代码。

    我偶尔会使用最底层的代码(多个使用语句),但除此之外,我总是使用大括号。我只是发现它使代码更清晰。从缩进中可以明显看出,语句是块的一部分(因此可能是if-etc的一部分)

    我已经看过了

    if (...)
        foo();
        bar();
    
    虫子咬了我一次(或者更确切地说是“我和同事”——我实际上并没有介绍虫子)。尽管我们当时的编码标准建议在任何地方都使用大括号,但这是事实。我花了很长时间才发现——因为你看到了你想看到的。(这是大约10年前的事了。也许我现在会发现它更快。)


    当然,如果你使用“线尾括号”,它会减少额外的线,但我个人不喜欢这种风格。(我在工作中使用它,发现它没有我预期的那么令人不快,但它仍然有点令人不快。)

    大多数时候,它作为编码标准根深蒂固,无论是对于公司还是自由和开放源码软件项目

    最终,其他人将需要摸索您的代码,对于每个开发人员来说,找出他们正在处理的代码部分的特定样式是一个很大的时间消耗


    另外,假设有人每天不止一次地在Python和Cish语言之间穿梭。。。在Python中,缩进是语言块符号的一部分,很容易犯你引用的错误。

    主要问题之一是当你有一行和非一行区域时, 以及与控制状态的分离(
    用于
    如果
    ,您有什么)和状态的结束

    例如:

    for (...)
    {
      for (...)
        for (...) 
        {
          // a couple pages of code
        }
      // which for block is ending here?  A good text editor will tell you, 
      // but it's not obvious when you're reading the code
    }
    
    我同意“如果你足够聪明,可以让别人付钱给你来编写代码,那么你应该足够聪明,不要仅仅依靠缩进来查看代码流。”


    然而。。。错误是可以犯的,这是一个痛苦的调试。。。特别是当你进来查看别人的代码时。

    为了避免带大括号的代码占用大量空间,我使用了本书中推荐的技巧:


    我总是在适当的时候省略它们,比如在你的第一个例子中。通过浏览我可以看到和理解的干净、简洁的代码比我必须滚动浏览和逐行阅读的代码更容易维护、调试和理解。我想大多数程序员都会同意这一点

    如果您开始执行多个嵌套、if/else子句等,它很容易失控,但我认为大多数程序员应该能够知道在哪里划清界限


    我觉得它有点像if(foo==0)vs
    if(0==foo)
    的参数。后者可以防止新程序员(甚至可能偶尔对老手)出现bug,而前者在维护代码时更容易快速阅读和理解。

    反对使用大括号的主要理由是它们使用额外的行,并且需要额外的缩进

    行是(几乎)免费的,最小化代码中的行数不应该是一个目标


    压痕与支撑的使用无关。在您的级联“使用”示例中,我仍然认为即使省略大括号,您也应该缩进它们。

    我曾经是“大括号是必须的!”的大力支持者,但由于采用了单元测试,我发现我的单元测试保护无括号语句不受以下情况的影响:

    if (foo)
        snafu();
        bar();
    
    通过良好的单元测试,我可以自信地省略简单语句的大括号,以提高可读性(是的,这可能是主观的)

    或者,对于类似上面的内容,我可能会将其内联为:

    if (foo) snafu();
    

    这样,需要将bar()添加到条件中的开发人员将更容易认识到缺少大括号,并添加它们。

    如果是小括号,请这样写:

    if(foo()) bar();
    if (condition) DoSomething();
    DoSomethingElse();
    

    如果它足够长,可以分成两行,请使用大括号。

    我更喜欢大括号提供的清晰度。你确切地知道这意味着什么,不必猜测是否有人只是胡闹而不理他们(并引入了一个bug)。我唯一一次省略它们是当我把if和action放在同一行时。我不会那样做的
    if (...) {
        foo();
        bar();
    }
    else {
        ...
    }
    
    if (foo)
        snafu();
        bar();
    
    if (foo) snafu();
    
    if(foo()) bar();
    if (condition) action();  // ok by me
    
    if (condition) // normal/standard for me
    {
       action();
    }
    
    if (something)
        just one statement; // i find this ugly
    else
    {
        // many
        // lines
        // of code
    }
    
    if (something)
    {
        just one statement; // looks better:)
    }
    else
    {
        // many
        // lines
        // of code
    }
    
    #define BADLY_MADE_MACRO(x) function1(x); function2(x);
    
    if (myCondition) BADLY_MADE_MACRO(myValue)
    
    if( some_condition ) { do_some_operation; }
    
    if( some_condition )
    {
        do_some_operation;
    }
    
    if(a)
       if(b)
         c();
    else
       d();
    
    if(x < y)
        x = y;
    else
        y = x;
    
    if(x < y)
    {
        x = y;
        x++;
    }
    else
    {
        y = x;
        y++;
    }
    
    if (condition) Foo();   // normal, everyday code
    
    if (condition) 
    {
        // something non-trivial hapening; pay attention!
        Foo();
        Bar();
    }
    
    if(addCurleyBraces()) bugFreeSofware.hooray();
    
    if(addCurleyBraces())
        bugFreeSofware.hooray();
    
    if(addCurleyBraces()) {
        bugFreeSofware.hooray();
    }
    
    if (condition)
    {
        DoSomething();
    }
    
    DoSomethingElse();
    
    if (condition) DoSomething();
    
    DoSomethingElse();
    
    if (condition) DoSomething();
    DoSomethingElse();
    
    if (condition) 
        DoSomething();
    DoSomethingElse();
    
    if (condition)
    {
        DoSomething();
        DoSomethingElse();
    }
    
    if (condition) 
        DoSomething();
        DoSomethingElse();
    
    if (foo)
      bar();
    
    if (foo)
      bar();
      baz();
    
    if (foo) {
      bar();
      baz();
    }
    
    if (foo) {
      bar();
      baz();
    } else {
      qux();
    }
    
     if( debugEnabled ) 
          println( "About to save 1 day of work to some very important place.");
     saveDayData();
    
     if( debugEnabled ) 
     //     println( "About to save 1 day of work to some very important place.");
     saveDayData();
    
    if( object != null ) try { 
         object.close();
    } catch( .....
    
    if (foo) bar();
    
    if (foo)
    {
        bar(); //It is easy to put a breakpoint here, and that is useful.
    }
    
    foreach (Foo f in foos)
      foreach (Bar b in bars)
        if (f.Equals(b))
          return true;
    
    return false;
    
    foreach (Foo f in foos)
    {
      foreach (Bar b in bars)
      {
        if (f.Equals(b))
        {
          return true;
        }
      }
    }
    
    return false;
    
    if (condition1)
      if (condition2)
        doSomething();
      else (condition2)
        doSomethingElse();
    
    if (condition1)
      if (condition2)
        doSomething();
    else (condition2)
      doSomethingElse();
    
    if (condition1)
    {
      if (condition2)
        doSomething();
      else (condition2)
        doSomethingElse();
    }