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?
Extending With a Protocol
Erase your old code and replace it with the following:
protocol Number { // 1
func +(l: Self, r: Self) -> Self // 2
}
extension Double : Number {} // 3
extension Float : Number {}
extension Int : Number {}
infix operator ⊕ { associativity left precedence 140 }
func ⊕<T: Number>(left: [T], right: [T]) -> [T] { // 4
var minus = [T]()
assert(left.count == right.count, "vector of same length only")
for (key, v) in enumerate(left) {
minus.append(left[key] + right[key])
}
return minus
}
You’re doing quite a lot here, so let’s take a step back and break it down.
- You define a protocol called
Number
. - The
Number
protocol defines an operator called+
. - You create an extension for
Double
,Float
andInt
data types that causes them to adopt theNumber
protocol. - You use a type constraint that requires
T
to conform to theNumber
protocol.
Ultimately, you’re telling the compiler that the generic type T
understands the +
operand. Now that you’ve cleared the compile error, try out the operand with arrays of Double
s and, separately, with Int
s by adding the following code:
var doubleArray = [2.4, 3.6] ⊕ [1.6, 2.4]
var intArray = [2, 4] ⊕ [1, 2]
You’ll see the following in your console:
[4.0, 6.0] [3, 6]
The operand now works with multiple data types and involves no duplication of code. If you wanted to add more numeric types, you could simply add a markup extension conforming to Number
.
How Can I Use Overloading in Real Life?
Do you think I’d let you spend your time on this tutorial if I wasn’t convinced of its usefulness? :] This section will employ a practical example to give you a better idea of how to use overloading in your own projects.
Operators and CGPoints
For this demo, you’ll use the SKTUtils library, a collection of handy Sprite Kit helper classes, written for the second edition of our iOS Games by Tutorials book.
You can find the repo of the framework on github. Clone the Swift branch of the repo by typing the following into a Terminal window:
git clone https://github.com/raywenderlich/SKTUtils.git --branch swift
Alternatively, you can download the ZIP of the Swift branch from github.
Note: Since Xcode 6 beta 5, it’s possible to import your own library within a playground sheet. All you need to do is have the framework and playground bundled together in a workspace. If you’d like to know more about this, read my post Playground has never been so fun.
Note: Since Xcode 6 beta 5, it’s possible to import your own library within a playground sheet. All you need to do is have the framework and playground bundled together in a workspace. If you’d like to know more about this, read my post Playground has never been so fun.
Open SKUTils/Examples/Playground/SKUTils.xcodeworkspace and build the project (you must build the project at least once for the associated framework to be compiled).
Then navigate to MyPlayground.playground from the project navigator. Delete what is currently in the playground and add the following code:
import SKTUtils
let pt1 = CGPoint(x: 10, y: 20)
let pt2 = CGPoint(x: -5, y: 0)
let pt3 = pt1 + pt2
let pt4 = pt3 * 100
You might be surprised to see that you’re successfully using the +
and *
operators on a CGPoint
without a word of complaint from the compiler.
{x 10 y 20} {x -5 y 0} {x 5 y 20} {x 500 y 2,000}
The magic here is coming from SKTUtils, which you’ve imported up top. Let’s take a closer look.
Overloading in SKTUtils
Navigate to SKTUtils/CGPoint+Extension.swift in the project navigator. You’ll see that this class defines an extension on CGPoint
that, among other things, overloads the +
operator as well as the corresponding compound assignment (+=
) operator.
public func + (left: CGPoint, right: CGPoint) -> CGPoint {
return CGPoint(x: left.x + right.x, y: left.y + right.y)
}
public func += (inout left: CGPoint, right: CGPoint) {
left = left + right
}
The code is similar to what you did earlier, but notice the access control set to public
. Access control restricts access to parts of your code from code in other source files and modules. As SKTUtils is a framework, its utilities need to be accessible from outside its module and it is thus defined as public.
The prestidigitation explained, there is no magic, after all—just smart coding!
Adding, subtracting, and multiplying CGPoint
s is a very common operation in games, so overloading operators to work on CGPoint
s greatly simplified the code in the book, making it much more concise and easier to read. I’m sure you can find similar examples in your own projects!
Operator overloading is a powerful feature of Swift that can make development much more efficient, if you do it with care.
Where to Go From Here?
You’ve reached the end of this tutorial—I hope you enjoyed it! You can find copies of the final playground files here and here.
If you’d like to learn more about operator overloading and Swift in general, check out our new book Swift by Tutorials.
I hope you find a way to use operator overloading in your own projects! But remember, with great power comes great responsibility – don’t be Troll Dev! ;]
If you have any questions or comments on this tutorial or on operator overloading in general, please join the forum discussion below!