Information is at the heart of nearly every iOS application we write. Information comes in, we write code to process it, we make decisions based on that information and then potentially take some action. But how exactly do we make those decisions?
Table of Contents
What is a Statement?
You may have heard the term before, but in Swift, a statement is everything that makes up a line (or in some cases several lines) of code.
This includes the keywords or tokens built into Swift, the names and types you use for your constants and variables, the operators you use in performing calculating as well as the optional semi-colon you may (though probably won’t) choose to include at the end of each statement.
In Swift there are three primary kinds of statement:
- Simple Statements
- Compiler Control Statements
- Control Flow Statements
Simple Statements are the most common type of statement and consist of either expressions or declarations. We’ve already taken an in-depth looked at expressions and declarations in this previous post here.
Compiler Control Statements are the second of the three groups. These are used to change how the Swift compiler itself behaves. This is an advanced topic and so for now, we’re going to leave these statements for a future article.
Control Flow Statements are the third of our three groups. This control flow statements are used to control the flow of execution within our program and it is this group that we’re going to focus on within this article.
Control Flow Statements
In Swift, the control flow statements can be broken down into three main subgroups:
- Loop Statements
- Branch Statements
- Control Transfer Statements
Loop statements allow a block of code to be execute repeatedly, either indefinitely or until some condition is no longer true. There are four main types of loop statement; the for-condition-increment
loop that will soon be removed in Swift 3.0, the for-in
loop, the while
loop and the repeat-while
loop. I’ve already covered loop statements in detail in this post so I’m not going to go into any more detail here.
The second group of control flow statements in Swift are the Control transfer statements. The control transfer statements provide a way to alter the order in which code is executed and include the break
, continue
and return
statements. They are usually used in conjunction with the other control flow statements so I’m going to leave them until a future post for now so that we can cover the other control flow statements first.
The final group of control flow statements in Swift are the branch statements. The brand statements provide provide our basic decision making capabilities within Swift. This group of statements allows us to take different paths through our code, executing different code blocks based on the outcomes of one or more conditions.
Branch Statements
In Swift, there are three types of branch statement.
The first is the guard
statement which we’ve looked at in a previous post. The guard
statement executes statements depending on the value of a boolean expression and requires that the expression evaluates to true
for the code after the guard statement to be executed.
The second type of branch statement in Swift is the switch
statement. As with the guard statement the switch
statement allows certain blocks of code to be executed depending on the value of a control expression. The switch
statement then compares the against one or more cases. If a match is found, the code block associated with that case is executed. The switch
statement in Swift is much more powerful than you may be used to from other languages and we’re going to look at it in more detail in a future post.
For now though, let’s look at the third type of branch statement that is available in Swift, the if
statement.
If Statement
The if
statement in Swift is by far the most common form of branch statement that you will use and the good news is that it is probably the simplest to understand.
Let’s start with the basics.
The if
statement in Swift is used to optionally execute a block of code based the result of one or more boolean conditions.
The boolean condition it uses can be a single boolean expression or multiple expressions combined together using using Swift’s logical operators AND (&&
) or OR (||
). As with many other conditions in Swift, the boolean condition in an if
statement does not need to be wrapped within a set of parentheses (though you can if you want to) but it does need to result in a single value, and one that conforms to Swift’s BooleanType
protocol. 99% of the time, this means either a value of true
or false
.
In their most basic form, the if
statement in Swift has the following structure:
if <condition> {
// statements...
}
With the if
statement, the statements within the body of the if
statement will only executed if the statements condition evaluates to true
. In common terms the if
statement essentially means:
If this given condition evaluates to
true
then execute these statements with this code block.
We can have a look at an example of this below.
Say we were wanted to print out the value of a variable x
if and only if that value were great than or equal to 5
. We could do that as follows:
let x = 7
if x >= 5 {
print(x)
}
// 7
Here we declare a simple constant x
and initialise it with the value 7
. When the if
statement is encountered, the value of x
is compared to the literal value 5
using the greater than or equal to operator (>=
). The result of this comparison is a boolean value, in this case the value true
, and due to the fact it is true
, the body of the loop is then executed, printing the value of x
before exiting.
Let’s have a look at another example. What if I wanted to print out the value of x
if it was not equal to 5
:
let x = 7
if x != 5 {
print(x)
}
// 7
Ok, pretty simple still but what about slightly more complicated example? What about printing the value of y
only if it is greater than or equal to 5
and less than or equal to 10
. The reality is that this is not that much more complicated than our last example. This time we use Swifts logical operators to combine two different boolean expressions together:
let y = 10
if y >= 5 && y <= 10 {
print(y)
}
// 10
In the is case, we have two boolean expressions (y >= 5
and y <= 10
) combined together using Swift’s AND (&&
) operator. The AND operator requires both expressions to true
for the overall expression to evaluate to true
. In this case, because y
with a value of 10
is both greater than or equal to 5
and less than or equal to 10
, the body of the if
statement is executed and the value of y
is printed. Get the idea?
Ok, let’s take things one step further. In addition to being able to use an if
statement on its own, we can also combine the it with an else
clause.
If-Else Statement
The if-else
statement in Swift is a combination of the if
statement we just looked at along with an additional else
clause. The else
clause allows us to specify a separate code block which will executed if the if
statements boolean expression evaluates to false
.
The basic structure of the if-else
statement is as follows:
if <condition> {
// Executed if the condition evaluates to true
<oneOrMoreStatements>
} else {
// Executed otherwise
<oneOrMoreStatements>
}
You can think of the else
clause as a bit of a catch-all. Either, the condition evaluates to true
and the statements within the first code block are execute or in all other cases, the statements with the else
code block are executed.
Let’s have a look at another example. This time we’re going to look at how we can print two separate messages, one when the value of x
is less than or equal to 5
and one where the value is greater than 5
:
let x = 6
if x <= 5 {
print("x is less than or equal to 5")
} else {
print("x is greater than 5")
}
// x is greater than 5
This time, we set the value of our variable x
to 6
. When the if
statement is reached, the expression is first evaluated. In this case the expression (x <= 5
) evaluates to false
as x
is actually greater than 5
. This time then instead of executing the first code block, the code block associated with the else
clause is executed printing out the fact that x
is greater than 5
.
Chained If Statements
Now, we’ve just seen how combining the if
statement with an else
clauses can allow us to execute two different code blocks, one when the if
statements expression evaluates to true
and one when it evaluates to false
, but what if we wanted to execute more than two code blocks? For example, what if we wanted to print out three different messages; one when x
was less than 5
, one when it was equal to 5
and one when it was greater than 5
?
Well, this is where things get a little more interesting when it comes to the else
clause. As we saw in the last section, the else clause can be used to execute a code block if the if
statements expression evaluates to false
but that is not the only way we can use the else
clause. In addition to being able to use an else
clause on it’s own, we can also combine the else clause with another if
statement and its associated condition. This allows us to chain if
statements together. Let’s have a look at our new scenario:
let x = 6
if x < 5 {
print("x is less than 5")
} else if x == 5 {
print("x is equal to 5")
} else {
print("x is greater than 5")
}
// x is greater than 5
So let’s have a look at this bit-by-bit. First, we declare our constant x
and initialise it with the value 6
. We then start executing the if
statement.
This starts by first evaluating the first of the conditions (x < 5
). In this case, the condition evaluates to false
so the associated code block is not executed and execution continues with the else
clause. This time though, the else
clause is combined with an additional if
statement. The if
statement is then executed just like any other if
statement we’ve already looked at. This means the associated condition (x == 5
) is evaluated. Again, this evaluates to false
so the code within the associated code block is skipped and the else
condition is executed. In this case, the else
clause really is a catch-all. There is no if
statement associated with it, no further conditions so in all other cases, the code with the else
block will executed, printing out the fast that x
is greater than 5
.
Let’s look at an other example. What if we modified our example slightly and only wanted to print a message if the value of x
is either less than 5
or equal to 5
but didn’t want to print anything out for all other cases. Well as we saw when we first looked at the if
statement, the else
clause of the if
statement is actually optional. With this in mind, we can therefore chain two if
statements together but are not obliged to include an else
clause:
let x = 6
if x < 5 {
print("x is less than 5")
} else if x == 5 {
print("x is equal to 5")
}
// No output.
In this example, I’ve omitted the catch-all else
clause we saw in the last example. The execution of the first two stages of the chained if
statement work in exactly the same manner as we just went through. This time though, when the condition of the second if
statement (x == 5
) evaluates to false, there is no else
clause to execute so execution continues immediately after the closing brace.
Nested If Statements
The next thing I want to talk about with regards to if
statements is nesting.
As we saw in my post on loops
, many of the control flow statements in Swift support the concept of nesting where one statement can be nested within the body of an other and the if
statement is no exception.
For example, say we wanted to modify our example slightly and print a message if the value of our variable was less than 5
but print whether the value was odd or even if the value was greater than or equal to 5
. Lets give it a go:
let x = 7
if x < 5 {
print("x is less than 5")
} else {
if x % 2 == 0 {
print("x is an even number.")
} else {
print("x is an odd number.")
}
}
Now, I do want to raise a word of caution with regards to nested if
statements. You’ve probably heard the phrase before;
Just because you can, doesn’t mean you should.
Although nested if
statements can provide you with extra decision making power, you should minimise the number of levels of nesting that you use in your program. Additional levels of nesting make your code correspondingly more difficult to read and in Swift, there are a number of other branching statements such as the switch
statement that can often achieve the same result but more elegantly. Just try to keep it in mind.
Anyway, that about wraps it up for today. As we’ve seen, the basic syntax for the if
statement in Swift is pretty simple but when combined with the else
clause and multiple boolean conditions can be a powerful way of changing the behaviour of your application by executing different paths through your code. As ever, if you have any questions or need more information don’t hesitate to get in touch.