代码之家  ›  专栏  ›  技术社区  ›  WW.

在IF块中放什么,在ELSE块中放什么?

  •  12
  • WW.  · 技术社区  · 16 年前

    这是一个次要的风格问题,但添加到代码中的每一点可读性都很重要。

    所以如果你有:

    if (condition) then
    {
       // do stuff
    }
    else
    {
       // do other stuff
    }
    

    你如何决定是这样更好,还是这样更好:

       if (!condition) then
       {
         // do other stuff
       {
       else
       {
         // do stuff
       }
    

    我的启发是:

    1. 保持条件为正(小于 阅读时的心理计算)
    23 回复  |  直到 16 年前
        1
  •  18
  •   cfeduke    16 年前

    我更喜欢把最常见的路径放在第一位,我坚信减少筑巢,所以我会尽可能打破、继续或返回,而不是埃尔辛。我通常更喜欢针对正面条件进行测试,或者将负面条件反转为正面条件。

    if (condition)
        return;
    
    DoSomething();
    

        2
  •  4
  •   finnw    16 年前

    两个(相互矛盾的)教科书引用:

    放置if/else的最短子句 最上面

    --艾伦·霍卢布,“足够的绳子射中你自己的脚”,第52页

    将正常情况置于if之后,而不是else之后

    --史蒂夫·麦康奈尔,“代码完成,第二版”,第356页

        3
  •  3
  •   workmad3    16 年前

    我喜欢第一个。条件应该尽可能简单,并且应该相当明显,哪种情况下更简单,哪种情况下更简单!条件

        4
  •  3
  •   Oli    16 年前

    bool MyFunc(variable) {
        if (variable != something_i_want)
            return false;
    
        // a large block of code
        // ...
        return true;
    }
    

    如果我需要 每种情况下,我都会使用 if (positive_clause) {} else {} 总体安排

        5
  •  3
  •   Simon Howard    16 年前

    如果代码要检查错误条件,我宁愿将该代码放在第一位,“成功”代码放在第二位;从概念上讲,这使函数调用及其错误检查代码保持在一起,这对我来说很有意义,因为它们是相关的。例如:

      if (!some_function_that_could_fail())
      {
         // Error handling code
      }
      else
      {
         // Success code
      }
    
        6
  •  3
  •   Dana    16 年前

    我同意奥利在可能的情况下使用积极的if子句。

    请不要这样做:

    if (somePositiveCondition)
    else {
        //stuff
    }
    

    我曾经在一个我工作过的地方看到过很多这样的情况,我曾经想知道是否有一个编码员不明白为什么不工作。。。

        7
  •  3
  •   Ken Ray    16 年前

    当我查看数据验证时,我尝试将我的条件设置为“白名单”——也就是说,我测试我将接受什么:

    if DataIsGood() then
       DoMyNormalStuff
    else
       TakeEvasiveAction
    

    而不是相反,它往往退化为:

    if SomeErrorTest then
      TakeSomeEvasiveAction
    else if SomeOtherErrorCondition then
      CorrectMoreStupidUserProblems
    else if YetAnotherErrorThatNoOneThoughtOf then
      DoMoreErrorHandling
    else
      DoMyNormalStuff
    
        8
  •  2
  •   Timothy Khouri    16 年前

    我知道这不是你想要的,但是。。。许多开发人员使用一个“guard子句”,即一个否定的“if”语句,该语句会尽快脱离方法。在这一点上,没有真正的“其他”。

    例子:

    if (blah == false)
    {
        return; // perhaps with a message
    }
    
    // do rest of code here...
    

    有一些核心的c/c++/汇编人员会告诉你,你正在破坏你的CPU!!!(在许多情况下,处理器倾向于使用“true”语句,并尝试“预取”下一步要做的事情……因此理论上任何“false”条件都会刷新管道,并且速度会慢几微秒)。

    在我看来,我们正处在“更好”(更容易理解)的代码胜于几微秒CPU时间的时刻。

        9
  •  2
  •   Vinko Vrsalovic    16 年前

    永远不要给变量命名,如果需要的话,使用同义词表并找到相反的名称。我见过很多像这样糟糕的代码

    if (not_dead) {
    } else {
    }
    

    而不是显而易见的

    if (alive) {
    } else {
    }
    

    if (!alive) {
    } else {
    }
    

    if (dead || (!dead && sleeping)) {
    } else {
    }
    

    也就是说

    if (dead || sleeping) {
    } else {
    }
    

    始终注意条件是什么,以及如何简化它们。

        10
  •  2
  •   S.Lott    16 年前

    软件是知识的获取。你在编码某人关于如何做某事的知识。

    软件应该符合问题的“自然”要求。当有疑问时,问问其他人,看看人们到底说了什么,做了什么。

    “常见”情况是什么都不做?然后呢

    if( common ) {
        // pass
    }
    else {
        // great big block of exception-handling folderol
    }
    

    if( ! common ) {
        // great big block of except-handling folderol
    }
    

    “总是积极的”规则并不是你首先想要的。您希望看到更像下面这样的规则。

    1. 总是自然的——它应该读起来像英语(或者组织中的通用语言)
    2. 在可能的情况下,首先是常见案例——因此它们看起来很常见。
    3. 在可能的情况下使用积极逻辑;消极逻辑可以用在通常这样说的地方,也可以用在通常情况下无所事事的地方。
        11
  •  2
  •   Community Tales Farias    7 年前

    Holub rule mentioned here 并将较短的代码放入if。这使得在查看代码时更容易在一个屏幕上看到if/else流。

        12
  •  1
  •   Ian Jacobs    16 年前

    对我来说,这取决于条件,例如:

    if (!PreserveData.Checked)
    {  resetfields();}
    

    我倾向于用我想要的逻辑与自己交谈,并将其编码为我头脑中的小声音。

        13
  •  1
  •   Patrick McElhaney    16 年前

    通常可以使条件为正,而无需切换if/else块。

    改变

       if (!widget.enabled()) {
         // more common 
       } else {
         // less common 
       }
    

       if (widget.disabled()) {
         // more common 
       } else {
         // less common
       }
    
        14
  •  1
  •   Ian Boyd    16 年前

    英特尔奔腾分支预测预取“如果”情况的指令。如果它改为跟随“else”分支:它将刷新指令管道,从而导致暂停。

    如果你非常关心绩效:将最可能的结果放在“如果”子句中。

    if (expected)
    {
       //expected path
    }
    else
    {
       //fallback other odd case
    } 
    
        15
  •  1
  •   Chris B-C    16 年前

    另一方面,如果您使用的是Perl之类的语言,特别是如果您的false条件是错误条件或最常见的条件,则可以使用“除非”结构,该结构执行代码块,除非条件为true(即与if相反):

    unless ($foo) {
        $bar;
    }
    
        16
  •  1
  •   Yarik    16 年前

    那么,让我们假设一定有一个“else”子句。

    我认为可读性/可理解性至少会带来三个关键要求或规则,不幸的是,它们经常相互竞争:

    1. 第一个块(if块)越短,就越容易掌握整个if-else结构。当“if”块足够长时,就很容易忽略“else”块的存在。

    2. 当“if”和“else”路径在逻辑上不对称(例如“正常处理”与“错误处理”)时 独立的 倍数 “if-else”构造彼此接近(包括嵌套),并且当所有这些“if-else”构造都具有相同类型的不对称性时,一致地排列这些不对称路径非常重要。

      同样,它可以是“如果……正常路径……其他……异常路径”,也可以是“如果……异常路径……其他……正常路径”,但它不应该是这两种变体的混合。

      在所有其他条件相同的情况下,将正常路径放在第一位对大多数人来说可能更自然(我认为这更多的是关于心理学而不是美学:-)。

    因此,我们有这三个相互竞争的要求/规则,而真正的问题是:其中哪一个比其他的更重要。对于Allen Holub来说,规则1可能是最重要的一条。对于史蒂夫·麦康奈尔来说,这是规则2。但我不认为你真的可以只选择这些规则中的一条作为单一的魁地林。

    我打赌你已经猜到了我个人的优先顺序(从我上面的规则排序来看:-)。

    我的理由很简单:

    • 规则#1是无条件的,不可能规避。如果其中一个块太长,以至于从屏幕上消失,那么它必须成为“else”块。(不,仅仅为了减少“if”或“else”块中的行数而机械地创建函数/方法不是一个好主意!我假设每个块都有一个 合乎逻辑的

    • 规则#2涉及很多条件:多个“if-else”结构,所有结构都具有相同类型的不对称性,等等。因此它在许多情况下并不适用。

      此外,我经常观察到以下有趣的现象:当规则#2确实适用并且正确使用时,它实际上并不与规则#1冲突!例如,每当我有一堆“正常与异常”不对称的“if-else”语句时,所有“异常”路径都比“正常”路径短(反之亦然)。我无法解释这种现象,但我认为这只是良好代码组织的标志。换句话说,每当我看到规则1和规则2发生冲突时,我就会开始寻找“代码气味”,而且通常我会找到一些;在重构之后——多田!在第1条规则和第2条规则之间做出选择再也没有痛苦了

    • 此外,正如其他同事在这里指出的,使用此规则“作弊”通常非常容易(例如,编写“如果(禁用)”,,,而不是“如果(!启用)…”)。

    我希望有人能理解这部作品。。。

        17
  •  0
  •   Kip    16 年前

    一般来说,如果一个比另一个大很多,我就把大一点的定为 if

        18
  •  0
  •   Andre Bossard    16 年前
    1. 把公共路径放在第一位
    2. !full == empty )
        19
  •  0
  •   J.J.    16 年前

    我总是把最有可能的放在第一位。

    在Perl中,我有一个额外的控制结构来帮助实现这一点。if的倒数。

    unless (alive) {
         go_to_heaven;
    } else {
         say "MEDIC";
    }
    
        20
  •  0
  •   dicroce    16 年前

    你应该总是把最有可能的情况放在第一位。除了可读性更好之外,它还更快。这也适用于switch语句。

        21
  •  0
  •   Vin King Vin King    16 年前



    if(userinput=null){

    }否则{
    实际做事;
    }



    如果(1+1=2){

    }否则{
    猛烈地爆炸();
    }

        22
  •  0
  •   user1479998 user1479998    12 年前

    我通常将肯定结果(方法)放在开头,因此:

    if(condition)
    {
    doSomething();
    }
    else
    {
    System.out.println("condition not true")
    }
    

    但如果使用的方法的条件必须为false,我会这样做:

    if(!condition)
    {
    doSomething();
    }
    else
    {
    System.out.println("condition true");
    }
    
        23
  •  0
  •   Monolo    12 年前

    如果您必须有多个出口点,请将它们放在第一位,并明确说明:

    if TerminatingCondition1 then
      Exit
    if TerminatingCondition2 then
      Exit
    

    if NormalThing then
      DoNormalThing
    else
      DoAbnormalThing