do {…} while(false)

前端 未结 25 2300
小鲜肉
小鲜肉 2020-11-28 03:29

I was looking at some code by an individual and noticed he seems to have a pattern in his functions:

 function()
{
 

        
相关标签:
25条回答
  • 2020-11-28 04:00

    Some coders prefer to only have a single exit/return from their functions. The use of a dummy do { .... } while(false); allows you to "break out" of the dummy loop once you've finished and still have a single return.

    I'm a java coder, so my example would be something like

    import java.util.Arrays;
    import java.util.List;
    import java.util.Set;
    import java.util.stream.Collectors;
    import java.util.stream.Stream;
    
    public class p45
    {
        static List<String> cakeNames = Arrays.asList("schwarzwald torte", "princess", "icecream");
        static Set<Integer> forbidden = Stream.of(0, 2).collect(Collectors.toSet());
    
        public static  void main(String[] argv)
        {
            for (int i = 0; i < 4; i++)
            {
                System.out.println(String.format("cake(%d)=\"%s\"", i, describeCake(i)));
            }
        }
    
    
        static String describeCake(int typeOfCake)
        {
            String result = "unknown";
            do {
                // ensure type of cake is valid
                if (typeOfCake < 0 || typeOfCake >= cakeNames.size()) break;
    
                if (forbidden.contains(typeOfCake)) {
                    result = "not for you!!";
                    break;
                }
    
                result = cakeNames.get(typeOfCake);
            } while (false);
            return result;
        }
    }
    
    0 讨论(0)
  • 2020-11-28 04:04

    I think it's more convenient to write break instead of goto end. You don't even have to think up a name for the label which makes the intention clearer: You don't want to jump to a label with a specific name. You want to get out of here.

    Also chances are you would need the braces anyway. So this is the do{...}while(false); version:

    do {
       // code
       if (condition) break; // or continue
       // more code
    } while(false);
    

    And this is the way you would have to express it if you wanted to use goto:

    {
       // code
       if (condition) goto end;
       // more code
    }
    end:
    

    I think the meaning of the first version is much easier to grasp. Also it's easier to write, easier to extend, easier to translate to a language that doesn't support goto, etc.


    The most frequently mentioned concern about the use of break is that it's a badly disguised goto. But actually break has more resemblance to return: Both instructions jump out of a block of code which is pretty much structured in comparison to goto. Nevertheless both instructions allow multiple exit points in a block of code which can be confusing sometimes. After all I would try to go for the most clear solution, whatever that is in the specific situation.

    0 讨论(0)
  • 2020-11-28 04:07

    This is just a perversion of while to get the sematics of goto tidy-up without using the word goto.

    It's bad form because when you use other loops inside the outer while the breaks become ambiguous to the reader. "Is this supposed to goto exit? or is this intended only to break out of the inner loop?"

    0 讨论(0)
  • 2020-11-28 04:07

    This trick is used by programmers that are too shy to use an explicit goto in their code. The author of the above code wanted to have the ability to jump directly to the "cleanup and return" point from the middle of the code. But they didn't want to use a label and explicit goto. Instead, they can use a break inside the body of the above "fake" cycle to achieve the same effect.

    0 讨论(0)
  • 2020-11-28 04:07

    In such cases I use

    switch(true) {
       case condution1:
          ...
          break;
       case condution2:
          ...
          break;
    }
    
    0 讨论(0)
  • 2020-11-28 04:10

    I think this is done to use break or continue statements. Some kind of "goto" code logic.

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