Javascript required
Skip to content Skip to sidebar Skip to footer

How to Continue a Loop After an Alert Swift

Swift's Break and Continue Statements

As I've mentioned in previous articles, there are three kinds of statement in Swift: simple statements such as expressions or declarations, compiler control statements that control aspects of the compilers behaviour and control flow statements that control the different paths through our code.

In previous posts we've already looked at some of the control flow statements such as the loop statements, the if statement and the guard statement. In this article we're going to continue on that journey by looking at Swift's break and continue statements. First though, we're going to look at statement labels.

Labelled Statements

In Swift we have the option of prefixing statements such as the if, switch do or loop statements with something called a statement label.

A statement label is nothing more than an identifier by which we can refer to that particular statement from elsewhere in our code. As such the statement identifier consisting of an identifier (much like an identifier you would use when declaring constants or variables) followed immediately by a colon (:) and then the statement that we want to label.

For example, say we wanted to provide a statement label for a for-in loop, we could write something like this:

                var x = 0 mainLoop: for x in 1...4 {     // Do stuff. }              

Here we've given the for-in loop the label mainLoop. The statement then follows after the colon. Once declared, that label can then be used anywhere within the scope of the labelled statement such as in the for-in loop itself.

We also have the option of nesting statement labels. For example, if we had a switch statement nested within our for-in loop above we could also give the switch statement it's own label. The only caveat with nested statement labels is that all the labels must be unique:

                var x = 0 mainLoop: for x in 1...4 {     innerSwitch: switch x % 2 {     case 0:         print("\(x) is even")     default:         print("\(x) is odd")     } } // 1 is odd // 2 is even // 3 is odd // 4 is even              

Here, the outer loop remains much as we just saw, but this time we also have a switch statement within the body of the loop that we've given the label innerSwitch.

Ok, pretty straight forward. By now you've probably got the hang of giving the different types of statement a label but you may also be wondering why you would want to. I promise, I will get to that shortly, but for now, let's move onto and look at the break statement. Once we've looked at that, we'll see how statement labels fit in.

The break Statement

In Swift, the break statement is used to immediately end the execution of a loop, a switch statement, an if statement of a do statement. As such, the break statement consists of a single break keyword followed optionally by a (you guessed it) statement label!

Let's look at using the non-labelled version of the break statement first.

When a break statement is NOT followed by a statement label, the break statement causes execution of a switch statement or the inner most enclosing loop within which the break statement occurs to immediately end it's execution. Execution then transfers control to the first statement after the closing curly brace of the named statement.

For example, say we had a switch statement, we could use a break statement within one of the cases to ignore that particular case:

                let x = 0 switch x { case 0:     break; case 1:      print("One for the money...") case 2:     print("Two for the road...") default:      print("Any other values"); } print("Finished") // Finished              

Here, the switch statement matches the value of x to the first case, where the break statement immediately transfers execution to the first statement outside of the closing brace (}) of the switch statement (the print statement).

There is however, another caveat. When using the break statement without an associated statement label we can't actually use it to break out of an unlabelled if statement or do statement. For example the following is NOT allowed:

                var x = 10 if x > 5 {     break // Causes a compiler error. }              

And this isn't either:

                do {     print("Hello World")     break // Causes a compiler error. }              

But slightly confusingly this is perfectly valid:

                var array = [1, 3, 6, 8, 2] for i in array {     if (i > 4) {         break     }     print(i) } // 1 // 3              

So what's going on?

What's happening here is that instead of the break statement applying to the unlabelled if statement (which we've just seen is not allowed), Swift applies the break statement to the for-in loop instead, terminating the loops execution as soon as it encounters a value that is greater than 4. Slightly confusing but now you know what to watch out for.

Ok, that's what happens if you use a break statement without an associated statement label, but what about if we include one?

Using break in Conjunction with Labelled Statements

When followed by a statement label, the break statement in Swift can be used to end the execution of the loop, if statement, switch statement or do statement that is identified by the supplied label.

This can sometimes be useful when working with nested statements, as it allows us to be explicit about which loop or conditional statement we want the break statement to affect.

Let's start off with a simple example. Remember our if statement that we couldn't break out of because it wasn't labelled? Well you can if you provide the if statement with a label:

                var x = 10 myCondition: if x > 5 {     break myCondition }              

Similarly this is also valid (though granted it's also a bit of a silly example):

                welcome: do {     print("Hello World")     break welcome }              

Where things get a little more interesting is when we combine a break statement with a label with nested statements:

                outer: for i in 1...5 {    inner: for j in 1...5 {         if (j * i) > 3 {             break outer         }         print("\(i) * \(j) = \(i * j)")    } } // 1 * 1 = 1 // 1 * 2 = 2 // 1 * 3 = 3              

In this example, we have two nested loops, one labelled outer and one labelled inner. Each of the loops iterates through the integer numbers 1 to 5. Within the body of the inner loop, we also have an if statement wrapped around our break statement which causes the break to only be executed when the product of j and i is greater than 3.

In this case, when the break statement executes, instead of terminating the inner loop (the loop labelled with inner) which it would do by default, the break statement actually terminates the outer loop (the loop labelled with outer) causing the entire nested loop construct to terminate and execution to continue immediately after the closing brace of the outer loop.

Ok, we've seen how to terminate execution of statements by using the break statement but what if we didn't want anything quite so drastic. What about if we simply wanted to skip the execution of the rest of a loop and wanted to continue with the next iteration? This is where our next statement the continue statement comes in.

Continue

In Swift, the continue statement tells a loop to stop what it is doing and to jump to the start of the next iteration of the loop. At that point, execution would continue with the the condition of the loop just like normal. In doing so, it essentially terminates the current iteration of the loop without exiting the loop as a whole, skipping the remaining statements within the body of the loop.

In similar fashion to the break statement, the continue statement consists of the continue keyword and is then optionally followed by a statement label. This obviously results in two forms; one with an associated label and on without.

When we use the continue statement on its own without a statement label, the statement terminates the execution of the current iteration of the inner most enclosing loop in which the continue statement occurs. Control is then transferred to the condition of that loop and execution continues as normal, either executing the next iteration of the loop or terminating.

We can see this in this example:

                for i in 1...3 {     for j in 1...3 {         if j == 2 {             continue         }         print("\(i) * \(j) = \(i * j)")     } } // 1 * 1 = 1 // 1 * 3 = 3 // 2 * 1 = 2 // 2 * 3 = 6 // 3 * 1 = 3 // 3 * 3 = 9              

In this example, we have two nested loops with each loop iterating through the integer numbers 1 to 3.

Within these loops is a nested if statement which checks the current iteration value of the inner loop to see if it is equal to 2. If it is, it executes the continue statement.

Each time the continue statement is executed, the current iteration of the inner for-in loop is terminated and execution starts at the next iteration of that inner loop. The result is that in those cases where the inner loop value is equals to 2, the print statement is skipped. We can see this with the output.

Ok, now what about if we use the continue statement with an associated statement label?

Using the continue Statement With an Associated Statement Label

As we saw with the break statement, the continue statement can also be followed with a statement label. When used in this manner, the continue statement causes the current iteration of the loop statement named by the label to be aborted and execution to continue with the next iteration of that loop.

In this next example, we have two nested loops, the outer one labelled with outer and the inner one labelled with inner:

                outer: for i in 1...3 {     inner: for j in 1...3 {         if j > 2 {             continue outer         }         print("i: \(i)  j: \(j)")     } } // i: 1  j: 1 // i: 1  j: 2 // i: 2  j: 1 // i: 2  j: 2 // i: 3  j: 1 // i: 3  j: 2              

Each loop iterates through the numbers 1 to 3. Once the loop value of the inner loop (j) exceeds 2, the continue statement executes and the outer loop is interrupted. Execution is then transferred to the condition of the outer loop statement where execution continues.

A Word of Warning About Labelled Statements

By now, you should have got a pretty good idea of how the break and continue statements work and how, in conjunction with labelled statements, you can construct some pretty complex logic within your applications. There is however a word of caution.

Due to the non-linear flow through your application that the use of labelled statements creates, it can make understanding your code more challenging.

For this reason, try to minimise your use of labelled statements using them only where absolutely necessary.

mockridgeexpriver.blogspot.com

Source: https://andybargh.com/break-and-continue/