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.