So far we have looked at using variables and constants in Swift and also described the different data types. Being able to create variables, however, is only part of the story. The next step is to learn how to use these variables and constants in Swift code. The primary method for working with data is in the form of *expressions*.

## Expression Syntax in Swift

The most basic Swift expression consists of an *operator*, two *operands* and an *assignment*. The following is an example of an expression:

var myresult = 1 + 2

In the above example, the (+) operator is used to add two operands (1 and 2) together. The *assignment operator* (=) subsequently assigns the result of the addition to a variable named *myresult*. The operands could just have easily been variables (or a mixture of constants and variables) instead of the actual numerical values used in the example. In the remainder of this chapter we will look at the basic types of operators available in Swift.

## The Basic Assignment Operator

We have already looked at the most basic of assignment operators, the = operator. This assignment operator simply assigns the result of an expression to a variable. In essence, the = assignment operator takes two operands. The left-hand operand is the variable or constant to which a value is to be assigned and the right-hand operand is the value to be assigned. The right-hand operand is, more often than not, an expression which performs some type of arithmetic or logical evaluation, the result of which will be assigned to the variable or constant. The following examples are all valid uses of the assignment operator:

var x: Int? // Declare an optional Int variable var y = 10 // Declare and initialize a second Int variable x = 10 // Assign a value to x x = x! + y // Assign the result of x + y to x x = y // Assign the value of y to x

## Swift Arithmetic Operators

Swift provides a range of operators for the purpose of creating mathematical expressions. These operators primarily fall into the category of *binary* operators in that they take two operands. The exception is the *unary negative operator* (-) which serves to indicate that a value is negative rather than positive. This contrasts with the *subtraction operator* (-) which takes two operands (i.e., one value to be subtracted from another). For example:

var x = -10 // Unary - operator used to assign -10 to variable x x = x - 5 // Subtraction operator. Subtracts 5 from x

The following table lists the primary Swift arithmetic operators:

Operator |
Description |

-(unary) |
Negates the value of a variable or expression |

* |
Multiplication |

/ |
Division |

+ |
Addition |

– |
Subtraction |

% |
Remainder/Modulo |

Note that multiple operators may be used in a single expression. For example:

x = y * 10 + z - 5 / 4

## Compound Assignment Operators

In an earlier section we looked at the basic assignment operator (=). Swift provides a number of operators designed to combine an assignment with a mathematical or logical operation. These are primarily of use when performing an evaluation where the result is to be stored in one of the operands. For example, one might write an expression as follows:

x = x + y

The above expression adds the value contained in variable x to the value contained in variable y and stores the result in variable x. This can be simplified using the addition compound assignment operator:

x += y

The above expression performs exactly the same task as *x = x + y* but saves the programmer some typing.

Numerous compound assignment operators are available in Swift, the most frequently used of which are outlined in the following table:

Operator |
Description |

x += y |
Add x to y and place result in x |

x -= y |
Subtract y from x and place result in x |

x *= y |
Multiply x by y and place result in x |

x /= y |
Divide x by y and place result in x |

x %= y |
Perform Modulo on x and y and place result in x |

## Comparison Operators

Swift also includes a set of logical operators useful for performing comparisons. These operators all return a Boolean result depending on the result of the comparison. These operators are *binary operators* in that they work with two operands.

Comparison operators are most frequently used in constructing program flow control logic. For example, an *if* statement may be constructed based on whether one value matches another:

if x == y { // Perform task }

The result of a comparison may also be stored in a *Bool* variable. For example, the following code will result in a *true* value being stored in the variable result:

var result: Bool? var x = 10 var y = 20 result = x < y

Clearly 10 is less than 20, resulting in a *true* evaluation of the *x < y* expression. The following table lists the full set of Swift comparison operators:

Operator |
Description |

x == y |
Returns true if x is equal to y |

x > y |
Returns true if x is greater than y |

x >= y |
Returns true if x is greater than or equal to y |

x < y |
Returns true if x is less than y |

x <= y |
Returns true if x is less than or equal to y |

x != y |
Returns true if x is not equal to y |

## Boolean Logical Operators

Swift also provides a set of so-called logical operators designed to return Boolean *true* or *false *values. These operators both return Boolean results and take Boolean values as operands. The key operators are NOT (!), AND (&&) and OR (||).

The NOT (!) operator simply inverts the current value of a Boolean variable, or the result of an expression. For example, if a variable named *flag* is currently true, prefixing the variable with a ‘!’ character will invert the value to false:

var flag = true // variable is true var secondFlag = !flag // secondFlag set to false

The OR (||) operator returns true if one of its two operands evaluates to true, otherwise it returns false. For example, the following code evaluates to true because at least one of the expressions either side of the OR operator is true:

if (10 < 20) || (20 < 10) { print("Expression is true") }

The AND (&&) operator returns true only if both operands evaluate to be true. The following example will return false because only one of the two operand expressions evaluates to true:

if (10 < 20) && (20 < 10) { print("Expression is true") }

## Range Operators

Swift includes several useful operators that allow ranges of values to be declared. As will be seen in later chapters, these operators are invaluable when working with looping in program logic.

The syntax for the *closed range operator* is as follows:

x…y

This operator represents the range of numbers starting at x and ending at y where both x and y are included within the range. The range operator 5…8, for example, specifies the numbers 5, 6, 7 and 8. The *half-open range operator*, on the other hand uses the following syntax:

x..<y

In this instance, the operator encompasses all the numbers from x up to, but not including, y. A half-closed range operator 5..<8, therefore, specifies the numbers 5, 6 and 7.

Finally, the *one-sided range *operator specifies a range that can extend as far as possible in a specified range direction until the natural beginning or end of the range is reached (or until some other condition is met). A one-sided range is declared by omitting the number from one side of the range declaration, for example:

x…

or

…y

The previous chapter, for example, explained that a String in Swift is actually a collection of individual characters. A range to specify the characters in a string starting with the character at position 2 through to the last character in the string (regardless of string length) would be declared as follows:

2…

Similarly, to specify a range that begins with the first character and ends with the character at position 6, the range would be specified as follows:

…6

## The Ternary Operator

Swift supports the *ternary operator* to provide a shortcut way of making decisions within code. The syntax of the ternary operator (also known as the conditional operator) is as follows:

condition ? true expression : false expression

The way the ternary operator works is that *condition* is replaced with an expression that will return either *true* or *false*. If the result is true then the expression that replaces the *true expression* is evaluated. Conversely, if the result was *false* then the *false expression* is evaluated. Let’s see this in action:

let x = 10 let y = 20 print("Largest number is \(x > y ? x : y)")

The above code example will evaluate whether x is greater than y. Clearly this will evaluate to false resulting in y being returned to the print call for display to the user:

Largest number is 20

## Nil Coalescing Operator

The *nil coalescing operator* (??) allows a default value to be used in the event that an optional has a nil value. The following example will output text which reads “Welcome back, customer” because the *customerName* optional is set to nil:

let customerName: String? = nil print("Welcome back, \(customerName ?? "customer")")

If, on the other hand, *customerName* is not nil, the optional will be unwrapped and the assigned value displayed:

let customerName: String? = "John" print("Welcome back, \(customerName ?? "customer")")

On execution, the print statement output will now read “Welcome back, John”.

## Bitwise Operators

As previously discussed, computer processors work in binary. These are essentially streams of ones and zeros, each one referred to as a bit. Bits are formed into groups of 8 to form bytes. As such, it is not surprising that we, as programmers, will occasionally end up working at this level in our code. To facilitate this requirement, Swift provides a range of *bit operators*.

Those familiar with bitwise operators in other languages such as C, C++, C#, Objective-C and Java will find nothing new in this area of the Swift language syntax. For those unfamiliar with binary numbers, now may be a good time to seek out reference materials on the subject in order to understand how ones and zeros are formed into bytes to form numbers. Other authors have done a much better job of describing the subject than we can do within the scope of this book.

For the purposes of this exercise we will be working with the binary representation of two numbers (for the sake of brevity we will be using 8-bit values in the following examples). First, the decimal number 171 is represented in binary as:

10101011

Second, the number 3 is represented by the following binary sequence:

00000011

Now that we have two binary numbers with which to work, we can begin to look at the Swift bitwise operators:

### Bitwise NOT

The Bitwise NOT is represented by the tilde (~) character and has the effect of inverting all of the bits in a number. In other words, all the zeros become ones and all the ones become zeros. Taking our example 3 number, a Bitwise NOT operation has the following result:

00000011 NOT ======== 11111100

The following Swift code, therefore, results in a value of -4:

let y = 3 let z = ~y print("Result is \(z)")

### Bitwise AND

The Bitwise AND is represented by a single ampersand (&). It makes a bit by bit comparison of two numbers. Any corresponding position in the binary sequence of each number where both bits are 1 results in a 1 appearing in the same position of the resulting number. If either bit position contains a 0 then a zero appears in the result. Taking our two example numbers, this would appear as follows:

10101011 AND 00000011 ======== 00000011

As we can see, the only locations where both numbers have 1s are the last two positions. If we perform this in Swift code, therefore, we should find that the result is 3 (00000011):

let x = 171 let y = 3 let z = x & y print("Result is \(z)")

### Bitwise OR

The bitwise OR also performs a bit by bit comparison of two binary sequences. Unlike the AND operation, the OR places a 1 in the result if there is a 1 in the first or second operand. The operator is represented by a single vertical bar character (|). Using our example numbers, the result will be as follows:

10101011 OR 00000011 ======== 10101011

If we perform this operation in a Swift example the result will be 171:

let x = 171 let y = 3 let z = x | y print("Result is \(z)")

### Bitwise XOR

The bitwise XOR (commonly referred to as *exclusive OR* and represented by the caret ‘^’ character) performs a similar task to the OR operation except that a 1 is placed in the result if one or other corresponding bit positions in the two numbers is 1. If both positions are a 1 or a 0 then the corresponding bit in the result is set to a 0. For example:

10101011 XOR 00000011 ======== 10101000

The result in this case is 10101000 which converts to 168 in decimal. To verify this we can, once again, try some Swift code:

let x = 171 let y = 3 let z = x ^ y print("Result is \(z)")

### Bitwise Left Shift

The bitwise left shift moves each bit in a binary number a specified number of positions to the left. Shifting an integer one position to the left has the effect of doubling the value.

As the bits are shifted to the left, zeros are placed in the vacated right most (low order) positions. Note also that once the left most (high order) bits are shifted beyond the size of the variable containing the value, those high order bits are discarded:

10101011 Left Shift one bit ======== 101010110

In Swift the bitwise left shift operator is represented by the ‘<<’ sequence, followed by the number of bit positions to be shifted. For example, to shift left by 1 bit:

let x = 171 let z = x << 1 print("Result is \(z)")

When compiled and executed, the above code will display a message stating that the result is 342 which, when converted to binary, equates to 101010110.

### Bitwise Right Shift

A bitwise right shift is, as you might expect, the same as a left except that the shift takes place in the opposite direction. Shifting an integer one position to the right has the effect of halving the value.

Note that since we are shifting to the right there is no opportunity to retain the lower most bits regardless of the data type used to contain the result. As a result, the low order bits are discarded. Whether or not the vacated high order bit positions are replaced with zeros or ones depends on whether the *sign bit* used to indicate positive and negative numbers is set or not.

10101011 Right Shift one bit ======== 01010101

The bitwise right shift is represented by the ‘>>’ character sequence followed by the shift count:

let x = 171 let z = x >> 1 print("Result is \(z)")

When executed, the above code will report the result of the shift as being 85, which equates to binary 01010101.

## Compound Bitwise Operators

As with the arithmetic operators, each bitwise operator has a corresponding compound operator that allows the operation and assignment to be performed using a single operator:

Operator |
Description |

x &= y |
Perform a bitwise AND of x and y and assign result to x |

x |= y |
Perform a bitwise OR of x and y and assign result to x |

x ^= y |
Perform a bitwise XOR of x and y and assign result to x |

x <<= n |
Shift x left by n places and assign result to x |

x >>= n |
Shift x right by n places and assign result to x |

## Summary

Operators and expressions provide the underlying mechanism by which variables and constants are manipulated and evaluated within Swift code. This can take the simplest of forms whereby two numbers are added using the addition operator in an expression and the result stored in a variable using the assignment operator. Operators fall into a range of categories, details of which have been covered in this chapter.