Another way to do it is to use else blocks on the for loops:
shared void run() {
variable Integer? x = null;
for (i in 0:3) {
for (j in 0:3) {
for (k in 0:3) {
value n = i*j*k;
if (n > 18) {
x = n;
break;
} else {
continue;
}
} else {
continue;
}
break;
} else {
continue;
}
break;
} else {
x = null;
}
print(x);
}
In general, place
else {
continue;
}
break;
after every for’s closing brace.
(Note: Ideally, the variable being assigned – x in my example, something in yours – wouldn’t need to be variable, since it’s assigned exactly once. However, the typechecker currently can’t prove that.)
How does it work? The else after a for loop is executed iff that loop ran to completion without any break. In that case, we want to continue the outer loop as well; otherwise – that is, if we broke from the inner loop – we want to break from the outer one as well.
This could be written more succinctly with the following syntax proposed in ceylon/ceylon#3223:
for (a in b) {
for (x in y) {
if (something) {
break;
}
} then { // opposite of else: runs iff there was a break in the inner loop
break;
}
}
I wouldn’t recommend this solution, for three reasons:
- It’s even less readable than your closure solution. The
for {} else {} feature is fairly obscure, and the meaning isn’t obvious at all if you’re not familiar with it, making the code incomprehensible to the casual reader.
- It bloats the code a lot in every surrounding loop (not just once), also making it unreadable.
- If you want to have code in the outer loops after the inner loops, you’ll have to duplicate it: the
else block and the code after it both need a copy.