Custom Operators in Swift

Thibault Carpentier
4 min readDec 7, 2017

--

Classes and structures can provide their own existing operator implementation or create completely new ones as needed. In this article we will study how operators work and how to use them correctly.

Overloading operators

We will start by giving you an example that creates a custom operator to make a sum ( + ). The addition in arithmetic is a binary operator because it uses 2 elements and it is infix because the operator ( + ) is between these two numbers.

The example below defines a Vector3D structure for a position in 3-dimensional space (x, y, z), followed by the definition of an operator function to allow the sum of 2 instances of Vector3D.

The operator function is defined as a global function with a name that corresponds to the operator that you wish to overload ( + ). As the addition is a binary operator, this operator function takes 2 input parameters of type Vector3D and returns a single value also of type Vector3D .

In this implementation, the input parameters are named left and right to represent the Vector3D that will be on the left side and the right side of the + operator. The function returns a new Vector3D whose values x and y and z correspond to the sums of x and y and z of the properties of the vectors given as parameters.

The function is defined globally, instead of being an instance method of a Vector3D , making the operator usable as an infix operator between 2 existing Vector3D.

Prefixed and Postfixed Operators

The previous example shows how to implement an infix binary operator. However classes and structures can also provide unary operator implementations. A unary operator operates on a single element and not two as a binary operator. They are prefixed if they precede the element (for example -a ) or postfixed if they follow the element (such as i++ ).

To implement a prefixed or postfixed unary operator, just add the prefix or postfix keyword in front of the operator function:

Unary operator

This example implements the unary minus ( -x ) operator for the Vector3D instances. This operator is prefixed and therefore uses the prefix keyword.

For a single numeric value, the unary operator minus converted positive numbers to their negative equivalence and vice versa. The equivalent implementation for vectors is to perform this operation on x ,y and z.

Compound Assignment Operators

Compound assignment operators allow assignments ( = ) to be combined with other operations. For example, the addition (as operator + ) can be combined with assignment ( = ) to form an addition assignment ( += ) which performs both in one operation. A compound assignment operator is declared with the use of the keyword inout on the left operation to allow it to be modified in the body of the function. The example below implements a function to create an addition assignment for a Vector3D :

It is important to note that the addition used in this operator is leveraging the implementation we saw earlier.

You can also combine declarations with either the prefix or postfix keyword such as below in this implementation of the prefixed prefix operator ( ++x ) for a Vector3D :

Equivalence Operator

Custom classes and structures do not have default implementations of equivalence operators, known as “equal to” (operator == ) and "not equal to" (operator != ). It is impossible in Swift to guess what is considered "equal" or not for your own custom types, because the meaning of "equal" depends on the roles these types play in your code.

To use the equivalence operator to check your types, it is necessary to provide an implementation of the operator in an infixed way:

In this example, we implement the operator “equal to” ( == ) and conform our Vector3D to the Equatable protocol. This protocol generates for us the != implementation and can make our life easier when trying to compare class storing Vector3D such as arrays. In context, a Vector3D is considered "equal to" another instance of Vector3D if their properties x, y and z are equal.

You can now use these operators to check if 2 instances of Vector3D are equivalent.

Custom Operators

You can declare and implement your own custom operators in addition to the standard operators provided in Swift.

New operators can be used by using the operator keyword and marked with the prefix, infix, or postfix keyword. Moreover, it can only be named using the character list provided here :

The example above defines a new prefix operator called +++ . It has no meaning in Swift and it will have its own meaning in the following example depending on the context: here with Vector3D . To illustrate this example, +++ is treated as an operator to double the value. It doubles the value of the x, y, and z of Vector3D

Priority and Associativity of Custom Infix Operators

Custom infix operators can also specify a priority and associativity. Check out the official documentation for an explanation of how associativity and priority affect operators.

The possible values ​​for associativity are left , right and none . Associativity on the left associates the left element if it is written next to another associativity operator to the left of the same priority. In the same way, an operator with associativity on the right associates the right element if it is written next to another associativity operator on the right. An operator with no associativity can not be written next to other operators with the same priority.

The following example sets a new infix operator called +-+ with an associativity on the left and a priority above the Addition priority:

This operator adds the properties x of the 2 vectors and at the same time subtracts the property y from the second vector with the first one and add the 2 properties z. Since it is an "additive" operator, it shoud have been given the same associativity and priority but the code shows a custom one as an example. For a complete list of the priorities and associativities of the operators provided by Swift in the standard library, take a look here .

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

No responses yet

Write a response