Operator Overloading in Swift Tutorial
Learn how to extend operators for new types or create entirely new operators in this new Swift tutorial! By Corinne Krych.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Operator Overloading in Swift Tutorial
25 mins
- Operators: An Overview
- Precedence
- Adding Isn’t Just for Ints
- Operator Overloading
- Defining Custom Operators
- Naming Your Operator
- Choosing a Type
- Assigning Precedence and Associativity
- Coding Your Custom Operator
- Bonus Round!
- Remember Related Operators!
- Defining Operators for More Than One Type
- Generics to the Rescue!
- Extending With a Protocol
- How Can I Use Overloading in Real Life?
- Operators and CGPoints
- Overloading in SKTUtils
- Where to Go From Here?
Note from Ray: This is a brand new Swift tutorial released as part of the iOS 8 Feast. Enjoy!
As you’ve learned in earlier tutorials in the iOS 8 Feast, Swift offers many powerful modern programming features, such as generics, functional programming, first class enums and structs, and more.
But there’s another new feature of Swift that you should know and love: operator overloading!
This is a fancy way of saying you can make operators like +
, -
, /
, or *
to work with any type you’d like! You can even define your own operators if you’re feeling especially creative.
For example, we use operator overloading in our Swift Sprite Kit utility library to add and multiply CGPoints
like this:
let pt1 = CGPoint(x: 10, y: 20)
let pt2 = CGPoint(x: -5, y: 0)
let pt3 = pt1 + pt2
let pt4 = pt3 * 100
Handy, eh? Get ready to overload your Swift development powers – to over 9,000!
Operators: An Overview
Begin by creating a new playground to help you explore operators.
Add the following line to your playground:
var simpleSum = 1 + 3
You’ll see the expected result:
4
There are two familiar operators in play here:
- First, you define a variable named
simpleSum
and set its value with the assignment operator (=
). - Second, you sum the two integers using the addition operator (
+
).
You’ll be overriding operators like these in this tutorial. But first, you need to understand the concept of precedence.
Precedence
You may remember from math class in school that rules of precedence apply to operators. These rules give some operators higher priority than others; higher-priority operators are applied first. For instance, you multiply before adding or subtracting.
Enter the following in your playground to confirm Swift operators follow these same rules:
var sumWithMultiplication = 1 + 3 - 3 * 2
You’ll see the following result:
-2
In cases where arithmetic operators have the same precedence, Swift evaluates the operators from left to right. In this example, this means operations are completed in the following order:
-
3 * 2
: subtraction. -
1 + 3
: Because the leftmost operator is applied first for operations with equal precedence. -
4 – 6
: This operation is completed upon the results of the prior operations.
Adding Isn’t Just for Ints
Integer arithmetic works as expected. But can you use the +
operator for other types as well?
It turns out you can! Try it for yourself by adding this line to your playground:
var sumArray = [1, 2] + [1, 2]
You might expect this to add each element of the same position together. Instead, you’ll see something like this:
[1, 2, 1, 2]
In this case, Swift interprets the +
as an append instruction. But what if you did want to add each element by position? This is known as vector addition.
Well, you could add a custom function to do this. Give it a try by adding the following to your playground:
func add(left: [Int], right: [Int]) -> [Int] {
var sum = [Int]()
assert(left.count == right.count, "vector of same length only")
for (key, v) in enumerate(left) {
sum.append(left[key] + right[key])
}
return sum
}
Here you define a global function that takes two integer arrays as input, checks that they have the same length, sums the values of each vector element and stores the resulting values in a new array.
Now add the following to confirm that your new function works:
var arr1 = [1, 1]
var arr2 = [1, 1]
var arr3 = add(arr1, arr2)
You’ll see the following in the console:
[2, 2]
It works! But rather than having to call a function do this, wouldn’t it be nice to use the +
operator instead?
With Swift, this is possible—with the power of operator overloading!
Operator Overloading
Operator overloading allows you to change the way existing operators work with specific structures or classes. This is exactly what you need – you’d like to change the way the +
operator works with Int
arrays!
Because operator overloading is global to the playground scope, start with a new playground sheet to avoid impacting your earlier examples. Then add the following to your playground:
func +(left: [Int], right: [Int]) -> [Int] { // 1
var sum = [Int]() // 2
assert(left.count == right.count, "vector of same length only") // 3
for (key, v) in enumerate(left) {
sum.append(left[key] + right[key]) // 4
}
return sum
}
You’ve just defined a global function called +
that takes two Int
arrays as input and returns a single Int
array. Here’s a breakdown of how it works:
- Note there’s nothing fancy about this function definition. It’s a normal function definition except you use
+
for the name! - Here you create an empty
Int
array. - This sample will only work with input arrays of the same length, and this
assert
enforces that. - You then enumerate through the left array, and sum each value with the corresponding value in the right array at the same position.
Test this function by adding the following to your playground:
var sumArray1 = [1, 2, 3] + [1, 2, 3]
Finally—the expected results of your vector addition operator! You will see the following in the console:
[2, 4, 6]
Of course, operator overloading isn’t all fun and games. It would be fairly confusing to someone jumping into your code if they were expecting the default behavior. For that matter, there’s nothing to stop you from overriding the +
operator to, for example, perform subtraction on integers—the risks are obvious!
Remember the operator overloading mantra: with great power comes great responsibility.
Typically, you’ll use overloading to extend an operation to a new object while maintaining the original semantics, rather than defining different (and confusing) behavior.
In this example, the behavior override does maintain semantics; vector addition is still a form of addition. But you may still want the ability to append arrays, and you want to avoid confusing yourself months down the road when you’ve forgotten you overrode the default behavior for Int
arrays.
Fortunately, Swift lets you create your own custom operators.