Swift Operators
Swift support most of the standard operator other programming language uses. In addition, Swift improves the safety while using these operators.
All standard operators are classified into 3 types of operator. They are:
- Unary Operator: Unary operator works with a single operand. It can be placed in front of an operand (prefix) or placed behind an operand (postfix). Examples of prefix unary operator are -variable1, -10 and !variable2. Example of postfix unary operator is variable3!
- Binary Operator: Binary operator works in between 2 operand. Examples of binary operator are a + b, c / d and e * f
- Ternary Operator: Ternary operator works with 3 operand. There is only one ternary operator in Swift; it is the ternary conditional operator (a ? b : c)
In a statement 1 + 2, the plus sign is the operator and the numbers are operands.
Assignment Operator
The most common and basic operator is the assignment operator. The basic syntax is as follows:
<variable_name> = <value/expression_that_fits_to_the_datatype>
Example:
var sampleNumber1 = 0
sampleNumber1 = 256 let sampleNumber2 = 242 sampleNumber1 = sampleNumber2 print(sampleNumber2) |
For tuples, we can assign multiple value to multiple variables/constant at once.
Example:
let (a, b, c) = (12, 2.78, "Test")
a b c |
Assignment Operator Do Not Return Value
Unlike other programming language, Swift assignment operator does not return a number or boolean value.
In C programming, we can combine assignment statement with if such as if a = b {...}. In C programming, a = b will return true if the assignment is successful.
We cannot combine assignment and if statement in Swift because the assignment statement in Swift do not return anything. To compare an assigned value we must use comparison operator.
Arithmetic Operator
Similar to other programming language, we have the standard arithmetic operator as shown below:
- Addition (+)
- Subtraction (-)
- Multiplication (*)
- Division (/)
The abovementioned arithmetic operator are binary operator and it work between 2 operand as shown in the example below:
12+54
132 - 65 23*65 9823 / 3 // For division, please be aware of floating point data type 9823 / 3.0 |
Additional Note:
- Please use floating point for division to get accurate result.
- Please note that any number divide by zero will return error
As previously mentioned in the data type section, we do not have integer overflow in Swift. Swift will return error for any attempt of integer overflow.
Example:
let intMax = Int.max
// intMax is 9223372036854775807 //let test1 = intMax + 1 //Above statement will generate error remove the comment for testing |
Remainder Operator
Remainder operator is denoted as %. This operator will return the remainder after a division is performed. For example 11 % 3 will return a remainder of 2 and 11 % 2 will give a remainder of 1. See example below.
Example
11 % 3
10 % 3 11 % 2 |
Rules of Remainder Operator
Swift use the following formula: a = (b * some multiplier) + remainder to derived the remainder. The sign of b is always ignore. Therefore, a % b and a % -b always give same answer. -a % b will give you negative number. Please also note that Swift remainder operator only work with integer and it doesn't work on floating point number.
Remainder Operator with Negative Number
The remainder operator also work with negative number. However the remainder will be negative only if the first operand (dividend) is negative. If the divisor is negative, the remainder will still be positive.
Example:
11 % 3
-11 % 3 11 % -3 -11 % -3 |
Modulus and Remainder Operator
A lot of programmers confuse between modulus and remainder operator. Some programming languages uses % as modulus operator and some programming language uses % as remainder operator.
Modulus operator and remainder operator yield the same result when performing division with positive number. The difference between the two types of operator differs when dealing with negative number.
See example below:
The following is the remainder operation using Swift:
The following is the modulus operation in Python 2.7 (available in Mac OS)
As shown above, if both dividend and divisor is positive or negative; the operator return the same result.
However, if dividend or divisor is negative, the result is different.
We would like to check when divisor is positive; what will happen to the remainder if we move the dividend from positive number to negative number.
Example:
for i in -12...12 {
print("\(i) % 3 is \(i % 3)") } |
The result is as follows
From the remainder operation, we know that once the dividend is negative, the remainder will be negative.
For modulus operation, whether the dividend is negative or positive, the remainder is always positive. In addition, the computation of mod is different from Swift when the dividend is negative. To derived -11 % 3, Python use the formula (-multiples x multiples) + modulus. In our example, the multiple is derived as -4 x 3 = -12. Therefore, -12 + modulus = -11 thus modulus is 1. Please note that modulus must be positive. we cannot use -9 and -2(modulus) to derived -11.
Please note that for C type of programming language, such as C, C#, Java, JavaScript and Swift; the implementation is the same. Programming language such as Python, Smalltalk, Perl, MATLAB, Haskell and Common LISP are using the other type of implementation.
Please also note that some programming language provides 2 difference kind of implementation. In Python, to implement the remainder operation similar to Swift or C, we need to use math.fmod.
Please note that for C type of programming language, such as C, C#, Java, JavaScript and Swift; the implementation is the same. Programming language such as Python, Smalltalk, Perl, MATLAB, Haskell and Common LISP are using the other type of implementation.
Please also note that some programming language provides 2 difference kind of implementation. In Python, to implement the remainder operation similar to Swift or C, we need to use math.fmod.
The previous section is not a comprehensive examination of difference between remainder and modulus operation. This is just a reminder to programmer that there are differences between modulus and remainder when we use them to deal with negative number.
Remainder for Floating Point Number
To use remainder for floating point number we can use the function remainder(_,_) or truncatingRemainder(dividingBy:)
Both functions produce different result. See example below"
We will not examine this in detail.
Unary Minus Operator
We can convert a positive number to negative number using the unary minus operator (-). See example below:
Example:
let a = 13
let b = -a let c = -b |
Note: We use the unary minus operator to convert from positive number to negative number. We can also use the same operator to convert negative number to positive number as shown above.
Unary plus operator has no effect in Swift.
Application of Arithmetic Operator
Example:
let unitPrice = 25.5
let quantity = 12546 let deposit = 10034.80 let amount = unitPrice * Double(quantity) let discount = amount * 0.05 let discountAmount = -discount let payableAmount = amount + discountAmount |
// Continuation from previous code
let salesTax = payableAmount * 0.07 let totalAmount = payableAmount + salesTax let cashPayment = totalAmount - deposit let totalUnitCost = totalAmount / 12546 |
Compound Assignment Operator
Compound assignment operator such as a += x is a short form of writing a = a + x. We have the following type of compound assignment operator:
- Addition (+=) same as a = a + x
- Subtraction (-=) same as a = a - x
- Multiplication (*=) same as a = a * x
- Division (/=) same as a = a / x
- Remainder (%=) same as a = a % x
Example:
var a = 10
a -= 1 a *= 2 a /= 2 a += 2 a %= 2 |
Note:
Compound statement do not return value.
You cannot use the following
let var551 = var54 += 5
or
let var551 = (var54 += 5)
Example:
var 54 = 10
//let var551 = (var54 += 5) // Will generate error warning |
Comparison Operator
Comparison operator compare numbers and return if the test is true. The following are the comparison operators:
- Equal (==)
- Not Equal (!=)
- Greater than (>)
- Less than (<)
- Greater than OR Equal to (>=)
- Less than OR Equal to (<=)
Each comparison return a boolean value.
Example:
10 == 10
20 == 21 123 != 934 123 != 123 12476 > 887 12476 > 12476 12476 > 12477 768 < 409098 409098 < 409098 409099 < 409098 |
Example 2:
1776 >= 1775
1776 >= 1776 1776 >= 1777 7172 <= 7173 7172 <= 7172 7172 <= 7171 |
We can also compare tuples against tuples. The comparison worked by comparing each element from left to right. For equal (==) comparison, the system will compare the leftmost element with first element on the right; if it is equal and the result is true then the system will proceed to compare the second element. If it is not equal, the system will return false after the first comparison and stop the comparing operation.
let originalTuples = ("a", 12, 2.78)
// Only true when all element is true originalTuples == ("a",12,2.78) originalTuples == ("A",12,2.78) |
Similarly, for not equal operation (!=), the system will compare each element. If the result is false (Equal), the system will compare the next element. If the comparison result is true (Not Equal), the system will stop comparing.
let originalTuples = ("z", 10, 2.788)
// Only false when all element is false originalTuples != ("c",12,98) originalTuples != ("z",10,2.788) originalTuples != ("a",10,2.78) // previous statement 2.78 is != 2.788 |
We can use the greater or less than sign to compare tuples element. The system
let originalTuples = ("a", 14, 2.7888)
// For string or character it compares the ranking in the Unicode table
// b is greater than a
originalTuples > ("b", 14, 77.8)
// character "2" is smaller than "a", did not compare 55.8 vs 2.788
originalTuples > ("2", 14, 55.8)
// Return the last result since first 2 element is equal
originalTuples > ("a", 14, 0.8)
// Return the last result since first 2 element is equal
originalTuples > ("a", 14, 55.8)
// Return the second result since first element is equal, ignore last element
originalTuples > ("a", 56, 0.08)
// Return the second result since first element is equal, ignore last element
originalTuples > ("a", 3, 55.8)
|
Note:
Please note that we can compare character or string in addition of numbers. However, we cannot use greater than or less than sign for boolean variables. Using greater for less than sign for boolean variables will generate error. For Boolean variables, we can use equal or not equal comparison.
|
Example:
The following examples shows tuples comparison with Boolean variables
let someOriginalTuples = (true, false, 12)
someOriginalTuples == (false, false,12) someOriginalTuples == (true, false, 12) |
If we use Boolean variable with greater or less than sign, it will generate error.
Important Note:
The comparator operator is able to compare tuples with 6 element or less. If our tuples have 7 or more element, we must implement the comparison individually.
|
Example:
The following example shows the maximum number of element tuples can be used for comparison with comparison operator.
let someOriginalTuples3 = (1, 2, 3, 4, 5, 6)
someOriginalTuples3 > (0, 1, 2, 3, 4, 5) |
Example:
The following example shows failed comparison if we are comparing 7 or more element in a tuples.
To perform 7 element comparison, use the example below:
let someOriginalTuples4 = (1, 2, 3, 4, 5, 6, 7)
someOriginalTuples4.0 > 0 someOriginalTuples4.1 > 1 someOriginalTuples4.2 > 2 someOriginalTuples4.3 > 3 someOriginalTuples4.4 > 4 someOriginalTuples4.5 > 5 someOriginalTuples4.6 > 6 |
Ternary Conditional Operator
Ternary operator consist of 3 parts. The syntax is as follows:
<query>?<answer1>:<answer2>
The system will evaluate the query and if the expression evaluate to true, then the system will return the evaluated value of answer1. If the query is false, the system will return the evaluated value of answer2.
Ternary operator is the condensed version of the following code:
if query {
answer1
} else {
answer2
}
Example:
var result = ""
let student1 = 65 result = student1 > 50 ? "pass" : "fail" print("Student 1 \(result)") |
The ternary operator is similar to the code below:
var result = ""
let student1 = 65 if student1 > 50 { result = "pass" } else { result = "fail" } print("Student 1 \(result)") |
As ternary operator is hard to understand, so we are encourage to use it wisely and avoid combining multiple ternary operation into one compound statement
Nil-Coalescing Operator
Nil-coalescing operator (??) unwraps the value of an optional variable if it is not nil. If the optional variable is nil, it will default to the second provided value. The syntax is as follows:
<optional_variable> ?? <value_used_when_optionl_is_nil>
For example, let consider userDefineColor ?? defaultColor. The variable userDefineColor is an optional. If there is value in this variable then the system will unwrap the value in this variable. If on the other hand this variable is found to be nil, then the system will use the value defaultColor.
The whole construct can be form using the program below:
if userDefineColor != nil {
colorUsed = userDefineColor
} else {
colorUsed = defaultColor
}
Example:
let defaultColor = "red"
let userDefinedColor:String? = nil let colorUsed = userDefinedColor ?? defaultColor print("Color used is \(colorUsed).") |
If our optional contains value, then the value will be unwrapped and utilized.
let defaultColor = "red"
let userDefinedColor:String? = "green" let colorUsed = userDefinedColor ?? defaultColor print("Color used is \(colorUsed).") |
Range Operator
There are three types of range operator, the closed range operator, half-open range operator and one-sided range operator.
Closed Range Operator
Closed range operator is represented by (...). Closed range operator include the begin number and end number. To use closed range operator, please follow the syntax:
<begin_number>...<end_number>
Example:
1...10
let set1 = 1...16 |
We can use close range operator to define a range of index as shown in the example below:
for index in 1...10 {
print("Item: \(index)") } |
Half-Open Range Operator
Half-open range operator is represented by (..<). It include the first number and the number less than the last number (last_number - 1). The syntax is as follows:
<begin_number>..<<last_number>
Example
for index in 1..<10 {
print("Item:\(index)") } |
Half-range operator is useful when referencing arrays or any data index that starts from 0 and ends at total count less one.
Example:
let myArrays = [0,1,2,3,4,5,6,7,8,9]
let count = myArrays.count for index in 0..<count { print("Number: \(index)") } |
Application of Range Operators
We can also use range operators as subscripts in an array. Listed below is an example using range operators with array.
let someArrayA = [1,2,3,4,5,6,7,8,9,10]
someArrayA[0] someArrayA[9] someArrayA.count someArrayA.last someArrayA[3...7] someArrayA[3..<7] |
We can also define range and use it in any other context besides subscripts:
// Define closed range
let someRange1 = 1...10 for index in someRange1 { print(index) } // Print 1 to 10 // Define half open range let someRange2 = 1..<16 for index in someRange2 { print(index) } // Print 1 to 15 |
One-Sided Range Operator
One-sided range operator is range operator without a beginning or end number. It can be apply to any closed range operator or half-open range operator.
One-Sided Close Range Operator
One-sided close range operator can be written as
...5 or 1…
|
The interpretation of one-sided operator is as follows:
- ...5 - tell the system to count from beginning of index (could be 0 or 1) to 5 inclusive.
- 1… - tell the system to count from 1 to the end of index.
One-Sided Half Open Range Operator
One-sided half open range operator can be written as
..<10
|
For half open range operator, Swift only support the one-sided half open range operator with the end index included as shown above.
We cannot do (0..<) as shown in the screen below.
Listed below is an example of application of one-sided range operator.
let someArrayB = [1,2,3,4,5,6,7,8,9,10]
someArrayB[0] someArrayB[9] someArrayB.count someArrayB.last someArrayB[3...7] someArrayB[1...] someArrayB[...7] someArrayB[3..<7] someArrayB[..<5] |
Limit of One-Sided Range Operator
We can also use one-sided range operator in any other context besides array subscripts. However, if the range is one-sided, what are the limits? The range is limited to the maximum and the minimum of an integer.
Please see example below:
// Define range from 1 t0 maximum of an Int can handle
let someRange3 = 1... someRange3.contains(100) someRange3.contains(100000000) let rangeMax = Int.max someRange3.contains(rangeMax) // Define range from Int minimum to 100 inclusive let someRange4 = ...100 someRange4.contains(10000) someRange4.contains(100) someRange4.contains(-11000000) let rangeMin = Int.min someRange4.contains(rangeMin) // Define range from Int minimum to 100 inclusive let someRange5 = ..<1000 someRange5.contains(1000) someRange5.contains(999) someRange5.contains(-766999) someRange5.contains(rangeMin) |
Please note that if we enter a number that is beyond the limits of an integer, runtime or compile error will occurs.
|
Logical Operator
In Swift, we support 3 logical operator, they are the NOT, AND and OR.
- NOT operator is denoted as !
- AND operator is denoted as &&
- OR operator is denoted as ||
Logical NOT Operator
We can use logical NOT operator as a unary prefix. A NOT in front of true will be false and vice versa. The syntax of using NOT operator is as follows:
!<variable/data>
Example
let myTruth = false
let myNewTruth = !myTruth print("My truth is \(myTruth) and my new truth is \(myNewTruth).") |
Logical AND Operator
We use logical AND operator as a binary operator in between 2 operand. The syntax of using AND operator is as follows:
<variable/data> && <variable/data>
Example
let myDoorCode = true
let myFingerPrint = false if myDoorCode && myFingerPrint == true { print("Access Granted") } else { print("Access Denied") } |
Note:
Please note that for AND operator, the system use short circuit evaluation. This means that the system will evaluate the left most conditional statement and if the first evaluation is false, the system will stop further evaluation because even if the second evaluation is true the result will still be false. We should place the statement that commonly generate false result on the left hand side of evaluation to increase efficiency.
|
Logical OR Operator
We use logical OR operator as a binary operator in between 2 operand. The syntax of using OR operator is as follows:
<variable/data> || <variable/data>
Example:
let myDoorCode = true
let myFingerPrint = false if myDoorCode || myFingerPrint == true { print("Access Granted") } else { print("Access Denied") } |
Note:
Similarly, for OR operator, the system also use short circuit evaluation. This means that the system will evaluate the left most conditional statement and if the first evaluation is true, the system will stop further evaluation because even if the second evaluation is false the result will still be true. We should place the statement that commonly generate true result on the left hand side of evaluation to increase efficiency.
|
Compound Logical Operator
We use multiple logical operator to form a compound expression. The system will evaluate the leftmost expression first and to the right. Please note that however && has precedence over ||. You need to evaluate && operation from left to right and then evaluate || from left to right.
Example:
let myDoorCode = true
let myFingerPrint = false let keyOverride = true let overridePassCode = true if myDoorCode && myFingerPrint || keyOverride && overridePassCode { print("Access Granted") } else { print("Access Denied") } |
In the example above, the system allowed 2 combination for user to enter the gate. Either the user enter the door code correct together with a correct fingerprint scan or; the user can use manual override key together with a correct override passcode.
To improve readability, the above example should be written as follows:
Operator AND has Precedence Against Operator OR
While we construct compound statement, please be aware that operator AND has a higher precedence level compared to operator OR.
Please check the example below:
// The following evaluate to true since AND has precedence over OR
true || false && false // To produce the false result we must use () as shown below (true || false) && false |
More example:
let condition1 = true
let condition2 = false let condition3 = true let condition4 = false condition1 || condition2 && condition3 && condition4 // Please note that && has precedence over || You need to evaluate && operation from left to right and then evaluate || from left to right |
Example:
true || false && true && false
true && false || false || true true && true || false && false false || true && true || false |
Operator Precedence
Operator precedence is the order of computing the operator. Consider the example below:
Example:
42 - 20 * 12 / 3 + 5 * 6 + 54
// The result is 46
For some programming language, all the arithmetic operator got the same precedence; this means that the system will evaluate the computation in the order from left to right. The result will be 612 if we evaluate from left to right.
Most programming language however, adopt the common precedence where multiplication and division have the same precedence but they are placed in a higher order than addition and subtraction.
In the example above, we should evaluate the multiplication and division first from left to right. After multiplication and division are evaluated, then we start evaluation addition and subtraction from left to right.
To change the order of precedence, such as we want to perform a subtraction first, we can add parenthesis to affect the order. Parenthesis has a higher precedence than the other arithmetic operator.
Example:
42 - 20 * 12 / 3 + 5 * 6 + 54
(42 - 20) * 12 / 3 + 5 * (6 + 54)
|
In the example above, the system will perform computation in the parenthesis first before resuming normal arithmetic operation. The result is different.
Similarly, we can also use parentheses to affect the order of evaluation when we use logical operator as shown in the previous section.
Listed below is a simplified table of the operator precedence. All operators under the same group have the same precedence. Left associative means the system will evaluate the expression from left to right. Right associative means that the system will evaluate the expression from right to left. Operator on the top of the list has higher precedence than the operator at the bottom of the list.
Precedence group
|
Operator
|
Description
|
Associativity
|
Primary Expression
|
( )
|
Parenthesis
|
Left associative
|
Prefix Operator
|
!
-
..<
... |
Logical NOT
Unary Minus
Half-open range
Closed range
|
None
None
None
None
|
Postfix Operator
|
...
|
Closed range
|
None
|
Multiplication
|
*
|
Multiply
|
Left associative
|
/
|
Divide
|
Left associative
| |
%
|
Remainder
|
Left associative
| |
Addition
|
+
|
Add
|
Left associative
|
-
|
Subtract
|
Left associative
| |
Range formation
|
..<
|
Half-open range
|
None
|
...
|
Closed range
|
None
| |
Nil-Coalescing
|
??
|
Nil-Coalescing
|
Right associative
|
Comparison
|
<
|
Less than
|
None
|
<=
|
Less than or equal
|
None
| |
>
|
Greater than
|
None
| |
>=
|
Greater than or equal
|
None
| |
==
|
Equal
|
None
| |
!=
|
Not equal
|
None
| |
Logical conjunction
|
&&
|
Logical AND
|
Left associative
|
Logical disjunction
|
||
|
Logical OR
|
Left associative
|
Ternary
|
?:
|
Ternary conditional
|
Right associative
|
Assignment
|
=
|
Assign
|
Right associative
|
*=
|
Multiply and assign
|
Right associative
| |
/=
|
Divide and assign
|
Right associative
| |
%=
|
Remainder and assign
|
Right associative
| |
+=
|
Add and assign
|
Right associative
| |
-=
|
Subtract and assign
|
Right associative
| |
Function Arrow
|
->
|
Function Arrow
|
Right associative
|
Explicit Parentheses
For complex expression, it is better to use bracket or parentheses to organize the expression. It also improve code readability.
Example:
let condition5 = true
let condition6 = false let condition7 = true let condition8 = false condition5 || condition6 && condition7 && condition8 // Evaluate to true as && take precedence before || // With parentheses the result may be different (condition5 || condition6) && (condition7 && condition8) |
***