Swift 3 Flow Control
Previous | Table of Contents | Next |
Swift Operators and Expressions | The Swift Switch Statement |
Learn SwiftUI and take your iOS Development to the Next Level |
Regardless of the programming language used, application development is largely an exercise in applying logic, and much of the art of programming involves writing code that makes decisions based on one or more criteria. Such decisions define which code gets executed, how many times it is executed and, conversely, which code gets by-passed when the program is executing. This is often referred to as flow control since it controls the flow of program execution. Flow control typically falls into the categories of looping control (how often code is executed) and conditional flow control (whether or not code is executed). This chapter is intended to provide an introductory overview of both types of flow control in Swift.
Looping Flow Control
This chapter will begin by looking at flow control in the form of loops. Loops are essentially sequences of Swift statements which are to be executed repeatedly until a specified condition is met. The first looping statement we will explore is the for loop.
The Swift for-in Statement
The for-in loop is used to iterate over a sequence of items contained in a collection or number range and provides a simpler alternative to the condition-increment looping technique previously described.
The syntax of the for-in loop is as follows:
for constant name in collection or range { // code to be executed }
In this syntax, constant name is the name to be used for a constant that will contain the current item from the collection or range through which the loop is iterating. The code in the body of the loop will typically use this constant name as a reference to the current item in the loop cycle. The collection or range references the item through which the loop is iterating. This could, for example, be an array of string values, a range operator or even a string of characters (the topic of collections will be covered in greater detail within the chapter entitled Working with Array and Dictionary Collections in Swift).
Consider, for example, the following for-in loop construct:
for index in 1...5 { print("Value of index is \(index)") }
Learn SwiftUI and take your iOS Development to the Next Level |
Value of index is 1 Value of index is 2 Value of index is 3 Value of index is 4 Value of index is 5
As will be demonstrated in the Working with Array and Dictionary Collections in Swift chapter of this book, the for-in loop is of particular benefit when working with collections such as arrays and dictionaries.
The declaration of a constant name in which to store a reference to the current item is not mandatory. In the event that a reference to the current item is not required in the body of the for loop, the constant name in the for loop declaration can be replaced by an underscore character. For example:
var count = 0 for _ in 1...5 { // No reference to the current value is required. count += 1 }
The while Loop
The Swift for loop described previously works well when it is known in advance how many times a particular task needs to be repeated in a program. There will, however, be instances where code needs to be repeated until a certain condition is met, with no way of knowing in advance how many repetitions are going to be needed to meet that criteria. To address this need, Swift provides the while loop.
Essentially, the while loop repeats a set of tasks while a specified condition is met. The while loop syntax is defined as follows:
while condition { // Swift statements go here }
In the above syntax, condition is an expression that will return either true or false and the // Swift statements go here comment represents the code to be executed while the condition expression is true. For example:
var myCount = 0 while myCount < 100 { myCount += 1 }
Learn SwiftUI and take your iOS Development to the Next Level |
If, on the other hand, myCount is not greater than 100 the code in the braces is executed and the loop returns to the while statement and repeats the evaluation of myCount. This process repeats until the value of myCount is greater than 100, at which point the loop exits.
The repeat ... while loop
The repeat … while loop replaces the Swift 1.x do .. while loop. It is often helpful to think of the repeat ... while loop as an inverted while loop. The while loop evaluates an expression before executing the code contained in the body of the loop. If the expression evaluates to false on the first check then the code is not executed. The repeat ... while loop, on the other hand, is provided for situations where you know that the code contained in the body of the loop will always need to be executed at least once. For example, you may want to keep stepping through the items in an array until a specific item is found. You know that you have to at least check the first item in the array to have any hope of finding the entry you need. The syntax for the repeat ... while loop is as follows:
repeat { // Swift statements here } while conditional expression
In the repeat ... while example below the loop will continue until the value of a variable named i equals 0:
var i = 10 repeat { i -= 1 } while (i > 0)
Learn SwiftUI and take your iOS Development to the Next Level |
Breaking from Loops
Having created a loop, it is possible that under certain conditions you might want to break out of the loop before the completion criteria have been met (particularly if you have created an infinite loop). One such example might involve continually checking for activity on a network socket. Once activity has been detected it will most likely be necessary to break out of the monitoring loop and perform some other task.
For the purpose of breaking out of a loop, Swift provides the break statement which breaks out of the current loop and resumes execution at the code directly after the loop. For example:
var j = 10 for _ in 0 ..< 100 { j += j if j > 100 { break } print("j = \(j)") }
In the above example the loop will continue to execute until the value of j exceeds 100 at which point the loop will exit and execution will continue with the next line of code after the loop.
The continue Statement
The continue statement causes all remaining code statements in a loop to be skipped, and execution to be returned to the top of the loop. In the following example, the print function is only called when the value of variable i is an even number:
var i = 1 while i < 20 { i += 1 if (i % 2) != 0 { continue } print("i = \(i)") }
The continue statement in the above example will cause the print call to be skipped unless the value of i can be divided by 2 with no remainder. If the continue statement is triggered, execution will skip to the top of the while loop and the statements in the body of the loop will be repeated (until the value of i exceeds 19).
Conditional Flow Control
In the previous chapter we looked at how to use logical expressions in Swift to determine whether something is true or false. Since programming is largely an exercise in applying logic, much of the art of programming involves writing code that makes decisions based on one or more criteria. Such decisions define which code gets executed and, conversely, which code gets by-passed when the program is executing. This is often referred to as flow control since it controls the flow of program execution.
Using the if Statement
The if statement is perhaps the most basic of flow control options available to the Swift programmer. Programmers who are familiar with C, Objective-C, C++ or Java will immediately be comfortable using Swift if statements.
The basic syntax of the Swift if statement is as follows:
if boolean expression { // Swift code to be performed when expression evaluates to true }
Unlike some other programming languages, it is important to note that the braces ({}) are mandatory in Swift, even if only one line of code is executed after the if expression.
Learn SwiftUI and take your iOS Development to the Next Level |
For example, if a decision needs to be made depending on whether one value is greater than another, we would write code similar to the following:
let x = 10 if x > 9 { print("x is greater than 9!") }
Clearly, x is indeed greater than 9 causing the message to appear in the console panel.
Using if ... else … Statements
The next variation of the if statement allows us to also specify some code to perform if the expression in the if statement evaluates to false. The syntax for this construct is as follows:
if boolean expression { // Code to be executed if expression is true } else { // Code to be executed if expression is false }
Using the above syntax, we can now extend our previous example to display a different message if the comparison expression evaluates to be false:
let x = 10 if x > 9 { print("x is greater than 9!") } else { print("x is less than 9!") }
Learn SwiftUI and take your iOS Development to the Next Level |
Using if ... else if ... Statements
So far we have looked at if statements which make decisions based on the result of a single logical expression. Sometimes it becomes necessary to make decisions based on a number of different criteria. For this purpose, we can use the if ... else if ... construct, an example of which is as follows:
let x = 9; if x == 10 { print("x is 10") } else if x == 9 { print("x is 9") } else if x == 8 { print("x is 8") }
This approach works well for a moderate number of comparisons, but can become cumbersome for a larger volume of expression evaluations. For such situations, the Swift switch statement provides a more flexible and efficient solution. For more details on using the switch statement refer to the next chapter entitled The Swift Switch Statement.
The guard Statement
The guard statement is a Swift language feature introduced as part of Swift 2. A guard statement contains a Boolean expression which must evaluate to true in order for the code located after the guard statement to be executed. The guard statement must include an else clause to be executed in the event that the expression evaluates to false. The code in the else clause must contain a statement to exit the current code flow (i.e. a return, break, continue or throw statement). Alternatively the else block may call any other function or method that does not itself return.
The syntax for the guard statement is as follows:
guard <boolean expressions> else { // code to be executed if expression is false <exit statement here> } // code here is executed if expression is true
The guard statement essentially provides an “early exit” strategy from the current function or loop in the event that a specified requirement is not met.
Learn SwiftUI and take your iOS Development to the Next Level |
func multiplyByTen(value: Int?) { guard let number = value , value < 10 else { print("Number is too high") return } let result = number * 10 print(result) }
The function takes as a parameter an integer value in the form of an optional. The guard statement uses optional binding to unwrap the value and verify that it is less than 10. In the event that the variable could not be unwrapped, or that its value is greater than 9, the else clause is triggered, the error message printed and the return statement executed to exit the function.
In the event that the optional contains a value less than 10, the code after the guard statement executes to multiply the value by 10 and print the result. A particularly important point to note about the above example is that the unwrapped number variable is available to the code outside of the guard statement. This would not have been the case had the variable been unwrapped using an if statement.
Summary
The term flow control is used to describe the logic that dictates the execution path that is taken through the source code of an application as it runs. This chapter has looked at the two types of flow control provided by Swift (looping and conditional) and explored the various Swift constructs that are available to implement both forms of flow control logic.
Learn SwiftUI and take your iOS Development to the Next Level |
Previous | Table of Contents | Next |
Swift Operators and Expressions | The Swift Switch Statement |