Best way to structure / new keyword

Some time ago, I came across the following construction, which I have rarely seen since, although I use it relatively often. I usually use it when checking the whole list of conditions is correct and prevents large levels of indentation. Essentially, it uses a for loop to create a kind of structured goto. My question first of all is whether there is a better way to structure this, secondly, whether people will like it, and thirdly, whether there will be a new keyword in java / C ++, etc., Such as unit { }, which will cause only breaks to exit to the end of the device, will be useful and understandable.

ps I understand that he is slipping away from an endless cycle, but I think that my paranoia about it means that he never was.

Edit: I added a setup code for further conditions, in order to try to highlight the problems with a chain, if then elses

boolean valid = false; // this loop never loops for (;;) { if (!condition1) break; condition2.setup(); if (!condition2) break; condition3.setup(); if (!condition3) break; valid = true; break; } if (valid) dosomething(); 

EDIT:

I just discovered that there really is a way to structure this in java without misusing loops, etc. and wondered if it looked like he would frown, although I think I missed the boat on this one.

The modified code is as follows.

 boolean valid = false; breakout: { if (!condition1) break breakout; condition2.setup(); if (!condition2) break breakout; condition3.setup(); if (!condition3) break breakout; valid = true; } if (valid) dosomething(); 

Now that the misuse of the for loop, which has caused a lot of complaints, is removed, and in fact this is a solution that I think is pretty neat and that is exactly what I was looking for. I guess this structure is probably not very well known, since no one mentioned it, do people object to it so much?

+4
source share
12 answers

I do not think this is the most readable way to do this. The if - else if chain looks a lot better. But if you want to stick to this and don't want to be so close to the infinite loop, you can do something like this:

 do { if (...) break; ... } while (false); 
+3
source

The loop is counter-intuitive and will be called into question when viewing the code: "Why do you need a loop if you always break the first iteration?"

Why not use this?

 boolean valid = true; if (!condition1) valid = false; else if (!condition2) valid = false; else if (!condition3) valid = false; if (valid) dosomething(); 
+16
source

You may have heard about these things that modern programming languages โ€‹โ€‹have called functions;) One of the main reasons goto no longer used is that now we can convert the code into separate functions and call them.

One way to solve your problem would be to put the code in a separate function instead and return instead of breaking from your pseudo-loop:

 void safedosomething() { if (!condition1) return; condition2.setup(); if (!condition2) return; condition3.setup(); if (!condition3) return; dosomething(); } 

or write auxiliary functions (for example, bool checkcondition1() { condition1.setup(); return condition1; } ) that set and then check the conditions and use the boolean flag:

 bool valid = true; if (!checkcondition1()) valid = false; if (!checkcondition2()) valid = false; if (!checkcondition3()) valid = false; if (!checkcondition4()) valid = false; if (valid) dosomething(); 

or a little more briefly:

 bool valid = true; valid &&= checkcondition1(); valid &&= checkcondition2(); valid &&= checkcondition3(); valid &&= checkcondition4(); if (valid) dosomething(); 

or simply

 if (checkcondition1() && checkcondition2() && checkcondition3() && checkcondition4()) dosomething(); 

There are many ways to express this, without counterintuitive loops - this is a non-loop.

+7
source

The reason for this design is that goto is a dirty word in programming. But let's face it, you are effectively using the loop construct to do the same. My opinion on this is either honest, or use goto or reorganize the code.

+4
source

Only C ++, unfortunately:

 if ( condition1 && (condition2.setup(), condition2) && (condition3.setup(), condition3) ) { dosomething(); } 

For something compatible with Java (but I'm still writing C ++!) I would like to go back to something like this. (Obviously, some context can be passed to CheckConditions() .)

 bool CheckConditions() { if (!condition1) return false; condition2.setup(); if (!condition2) return false; condition3.setup(); if (!condition3) return false; return true; } //... if (CheckConditions()) { dosomething(); } //... 
+3
source

It seems to you that some state is required to evaluate state 2, and you do not know where to put it. Refactor this into a separate boolean method, and then use the method that described almost everything here. For instance:

 if (checkCondition1() && checkCondition2(someInput) && checkCondition3()) { doSomething(); } 

and..

 private boolean checkCondition2(Object someInput) { //setup condition 2 return condition2; } 
+2
source

I think the problem is with

 if (condition1 && condition2 && ...) 

it was just that it would be difficult to read and edit if there are many conditions, although you can always write it like this:

 if ( condition1 && condition2 && condition3 ... ) doStuff(); 

How about including a loop in a function:

 bool all() { if (!condition1) return false; if (!condition2) return false; if (!condition3) return false; .... return true; } 
+1
source

Here's a kind of compromise if you want to keep the indentation as it is:

 boolean valid = true; // optimistic start if (!valid || !condition1) valid = false; if (!valid || !condition2) valid = false; if (!valid || !condition3) valid = false; if (valid) doSomething(); 

!valid in the first if is supernatural, but does no harm, can be preserved for readability. else/if more elegant in my opinion, but this is just an opinion.

But I really would not want to (ab-) use the for loop, and I will never find a cheap way to implement pseudo-goto. Always the best solution.

+1
source

I'm not sure why a loop is needed if there is a break statement at the end of the loop. Arent, you just repeat once, regardless of the situation?

Anyway, you'll usually find two different opinions about this on SO, one of which is that break statements should not be used at all, and one of them is that it depends on the situation.

I tend to the last group, but the way your loop works uses redundant break statements. I would rather structure such a loop as follows:

 bool valid = true; for(... ; .... && valid == true ; ....) { if (!condition1) valid = false; if (!condition2) valid = false; if (!condition3) valid = false; } 

This allows you to get out of the cycle, which I consider more elegant.

0
source

Having such a long if statement is most likely a bad coding.
This is very difficult to verify, and most likely the smell of code.

If possible, you should reorganize to take advantage of polymorphism.

0
source

How to move installation to bool statement in Condition class? This makes it more readable and hides the mechanics.

 class Condition { bool _isSet; public: Condition() : _isSet(false) { } void setup() { _isSet = true; } operator bool () { if (!_isSet) { setup(); } return rand() & 1; } }; void doSomething() { } int _tmain(int argc, _TCHAR* argv[]) { Condition cond1, cond2, cond3; if (cond1 && cond2 && cond3) { doSomething(); } return 0; } 
0
source

You can pass this code into a separate function and use several return statements. You will probably have to reorganize the long list of if into a separate function.

 bool isValid() { if (!condition1) return false; condition2.setup(); if (!condition2) return false; condition3.setup(); if (!condition3) return false; return true; } 

Then you can use it in your code:

 if (isValid()) dosomething(); 
0
source

Source: https://habr.com/ru/post/1332094/


All Articles