Tutorial

An Introduction to Operator Overloading in Swift


Operator overloading is one of the most powerful features of any computer programming language, so Apple decided to make it available for development in Swift. However, with great power comes great responsibility. You can easily implement really weird scenarios with it, such as making the subtraction operator add numbers or the division one multiply them, but that is definitely not what you want to do with it.

OK, enough talking – let’s see what operator overloading is all about.

The Challenge

Your task for this tutorial is an easy one: extend the multiplication operator’s standard functionality for numbers so that it works for strings as well. You are going to use the string concatenation operator under the hood, since you can imagine the whole thing like this:

Before diving into coding, think how you would solve the problem and break it into steps. This is how I would do it:

  • Create the result variable and assign its initial value – the default string.
  • Loop through the numbers from 2 to the number of concatenations and do only one thing for each iteration – add the string to the result.
  • Print the result to the console.

That’s it for the algorithm – let’s move on to the implementation.

Basic Operator Overloading

learn-operator-overloading

Fire up Xcode and open a playground. Delete everything from it and add the multiplication operator function’s prototype:

The function has two parameters – the left hand side operand of type String and the right hand side operand of type Int – and returns the multiplication result as String.

There are three things you should do inside the function’s body. First of all, create the result variable and assign its initial value – the function’s String argument – it is variable because you are going to change its value soon:

Next loop through the numbers from 2 to the function’s Int argument with the for in control flow statement and the closed range operator:

Note: You implement the wildcard pattern matching with the underscore since you ignore the sequence values – read more about loops here.

There is only one thing you should do in the loop – update the result with the string value:

Note: You could also do it like this – the initial approach is shorter because it uses the addition assignment operator:

Finally, return the result:

Now let’s use the operator:

That’s it! There is only one problem – you can only use the operator to multiply strings. How about other value types? Let’s fix this with generic operators.

Generic Operators

generic-operators

Generic types don’t work with operators by default, so you need a protocol for that. Add its prototype to the playground:

Now add the addition assignment operator function’s prototype to the protocol:

The function has both the left hand side and right hand side operands of type Self – this is just a fancy way of saying that they are of any type which implements the protocol. The left hand side operand is marked as inout, since its value is modified and returned from the function.

Alternatively, you can define the addition operator function’s prototype:

The function has both the left hand side and right hand side operands of type Self and returns the addition result as a value of type Self. In this case, you do not need to use inout parameters anymore.

Next, create extensions for the String, Int, Double and Float types that implement the Type protocol:

Note: The implementation of the extensions are empty because you don’t want to add anything to the default types. You simply make them in order to conform to the protocol.

Now add the multiplication operator function’s prototype to the playground file:

The function takes in two parameters – the left hand side operand of type T and the right hand side operand of type Int – and returns the multiplication result as a value of type T. You use a type constraint to make the generic type T conform to the Type protocol, so it now understands the addition assignment operator.

Note: You can define the type constraint with the where keyword instead – the initial approach is shorter though:

The function’s implementation is exactly the same as in the previous case:

Note: You can use the addition operator instead – make sure to add its function prototype to the protocol in this case.

Now let’s see the generic operator in action:

That’s it! There is only one problem: you are using the standard multiplication operator. That’s a bit confusing. It would better if we can change it to other operators. Okay, let’s see how we can fix this with custom operators.

Custom operators

custom-operators

Add this line to the playground file to get started:

Here’s what’s going on here, step-by-step:

  1. The custom multiplication operator’s name is **.
  2. Its type is infix since it is a binary operator with two operands.
  3. It evaluates from left to right, so it has a left associativity.
  4. Its precedence is 150 – the same as the standard multiplication operator’s one, since it is a high priority operator.

Note: You can read more about operator precedence and associativity here.

The custom operator function’s prototype is similar to the standard one – just its name is different:

The function’s implementation is exactly the same as before:

Here’s the custom operator in action:

That’s it! There is only one problem – the operator’s compound version is not defined yet, so let’s fix this in the next section.

Compound Operators

compound-operators

The compound operator’s type, precedence and associativity is exactly the same as in the previous case – only its name is different:

Next add the compound operator function’s prototype to the playground:

The function doesn’t have a return type, since its left hand side operand is marked as inout.

There is only one thing you should do in the function’s body – use the custom operator defined earlier to return the multiplication result:

Now let’s use the operator:

That’s it – it can’t get any simpler than that!

Conclusion

Operator overloading, used with caution, can be extremely powerful – I hope you find a way to use it in your own projects.

For reference, you can download the Playground file on GitHub. I have tested the code on Xcode 7.3 and Swift 2.2.

What do you think about this tutorial and operator overloading? Please leave me comment and share your thought.

Credit: The comic strips were created at MakeBeliefsComix.com.
Tutorial
Introduction to the Accelerate Framework in Swift
iOS
Introduction to React Native: Building iOS Apps with JavaScript
SwiftUI
Using AsyncImage in SwiftUI for Loading Images Asynchronously
Shares