How do you handle huge if-conditions?

后端 未结 21 1725
一向
一向 2021-01-31 17:14

It\'s something that\'s bugged me in every language I\'ve used, I have an if statement but the conditional part has so many checks that I have to split it over multiple lines, u

相关标签:
21条回答
  • 2021-01-31 17:33

    Well, first off, why not:

    if (var1 && var2 && var2 && var3 && var4 && var5 && var6) {
    ...

    Also, it's very hard to refactor abstract code examples. If you showed a specific example it would be easier to identify a better pattern to fit the problem.

    It's no better, but what I've done in the past: (The following method prevents short-circuiting boolean testing, all tests are run even if the first is false. Not a recommended pattern unless you know you need to always execute all the code before returning -- Thanks to ptomato for spotting my mistake!)

    boolean ok = cond1;
    ok &= cond2;
    ok &= cond3;
    ok &= cond4;
    ok &= cond5;
    ok &= cond6;

    Which is the same as: (not the same, see above note!)

    ok = (cond1 && cond2 && cond3 && cond4 && cond5 && cond6);

    0 讨论(0)
  • 2021-01-31 17:35

    In reflective languages like PHP, you can use variable-variables:

    $vars = array('var1', 'var2', ... etc.);
    foreach ($vars as $v)
        if ($$v == true) {
            // do something
            break;
        }
    
    0 讨论(0)
  • 2021-01-31 17:35

    @tweakt

    It's no better, but what I've done in the past:

    boolean ok = cond1; ok &= cond2; ok &= cond3; ok &= cond4; ok &= cond5; ok &= cond6;

    Which is the same as:

    ok = (cond1 && cond2 && cond3 && cond4 && cond5 && cond6);

    Actually, these two things are not the same in most languages. The second expression will typically stop being evaluated as soon as one of the conditions is false, which can be a big performance improvement if evaluating the conditions is expensive.

    For readability, I personally prefer Mike Stone's proposal above. It's easy to verbosely comment and preserves all of the computational advantages of being able to early out. You can also do the same technique inline in a function if it'd confuse the organization of your code to move the conditional evaluation far away from your other function. It's a bit cheesy, but you can always do something like:

    do {
        if (!cond1)
           break;
        if (!cond2)
           break;
        if (!cond3)
           break;
        ...
        DoSomething();
    } while (false);
    

    the while (false) is kind of cheesy. I wish languages had a scoping operator called "once" or something that you could break out of easily.

    0 讨论(0)
  • 2021-01-31 17:36

    McDowell,

    You are correct that when using the single '&' operator that both sides of the expression evaluate. However, when using the '&&' operator (at least in C#) then the first expression to return false is the last expression evaluated. This makes putting the evaulation before the FOR statement just as good as any other way of doing it.

    0 讨论(0)
  • 2021-01-31 17:37

    If you do this:

    if (var1 == true) {
        if (var2 == true) {
            if (var3 == true) {
                ...
            }
        }
    }
    

    Then you can also respond to cases where something isn't true. For example, if you're validating input, you could give the user a tip for how to properly format it, or whatever.

    0 讨论(0)
  •     if (   (condition_A)
            && (condition_B)
            && (condition_C)
            && (condition_D)
            && (condition_E)
            && (condition_F)
           )
        {
           ...
        }
    

    as opposed to

        if (condition_A) {
           if (condition_B) {
              if (condition_C) {
                 if (condition_D) {
                    if (condition_E) {
                       if (condition_F) {
                          ...
                       }
                    }
                 }
              }
           }
        }
    

    and

        if (   (   (condition_A)
                && (condition_B)
               )
            || (   (condition_C)
                && (condition_D)
               )
            || (   (condition_E)
                && (condition_F)
               )
           )
        {
           do_this_same_thing();
        }
    

    as opposed to

        if (condition_A && condition_B) {
           do_this_same_thing();
        }
        if (condition_C && (condition_D) {
           do_this_same_thing();
        }
        if (condition_E && condition_F) {
           do_this_same_thing();
        }
    

    Most of the static analysis tools for examining code will complain if multiple conditional expressions do not use explicit parenthesis dictating expression analysis, instead of relying on operator precedence rules and fewer parenthesis.

    Vertical alignment at the same indent level of open/close braces {}, open close parenthesis (), conditional expressions with parenthesis and operators on the left is an very useful practice, which greatly ENHANCES readability and clarity of the code as opposed to jamming everything that can possibly be jammed onto a single line, sans vertical alignment, spaces or parenthesis

    Operator precedence rules are tricky, e.g. && has higher precedence than ||, but | has precedence than &&

    So, ...

        if (expr_A & expr_B || expr_C | expr_D & expr_E || expr_E && expr_F & expr_G || expr_H {
        }
    

    is a really easy multiple conditional expression for mere humans to read and evaluate improperly.

        if (   (  (expr_A)
                & (expr_B)
               )
            || (  (expr_C)
                | (  (expr_D)
                   & (expr_E)
                  )
               )
            || (   (expr_E)
                && (  (expr_F)
                    & (expr_G)
                   )
               )
            || (expr_H)
           )
        {
        }
    

    There is nothing wrong with horizontal space (linefeeds), vertical alignment, or explicit parenthesis guiding expression evaluation, all of which ENHANCES readability and clarity

    0 讨论(0)
提交回复
热议问题