Operators Revisited: Overloading and Custom Operators - ADDITIONAL TOPICS - Understanding Swift Programming: Swift 2 (2015)

Understanding Swift Programming: Swift 2 (2015)

PART 3: ADDITIONAL TOPICS

25. Operators Revisited: Overloading and Custom Operators

In Swift, custom operators can be defined. If we would like to use a particular symbol to cause the execution of a particular piece of code, we can define the symbol as a custom operator and the necessary related operands.

Swift can also do operator overloading, in which the same operator is defined to work with more than one group of operands. The pattern of types of the operators in a particular situation determines which definition of the operator will be used for that particular situation.

Creating a Custom Operator

A custom operator in Swift is created in two steps. First, the operator is declared, which specifies the character or characters used for the operator and some parameters. And second, a function is implemented for the operator that performs the actual operation that the operator represents.

Suppose we'd like to implement a square root operator that uses the Unicode square root symbol √ . There's a square root function already existing in Swift, sqrt, but we think it's nicer to use the symbol.

The operator declaration requires the symbol, the keyword operator, and whether the operator is to be a prefix, infix, or postfix operator. It also can specify the precedence and associativity (parsing direction or none). In the case of a unary operator, or operator that takes only one operand, we don't need to specify the precedence or associativity.

We first need to import the Foundation framework so that the sqrt function works:

import Foundation // Needed for sqrt function

(Alternatively, UIKit can be used, which includes Foundation.)

We then use the following line of code to declare the operator:

prefix operator √{}

(The Unicode square root symbol √ can be entered on a Macintosh by pressing the V key with the option key held down.)

The function that implements the operator is as follows:

prefix operator √{}

prefix func √(x: Double) -> Double {

return sqrt(x)

}

print(√5) // Prints: 2.236067

(If you are entering this in the interactive REPL, you must enter the operator declaration just before the function definition, with no delay.)

The prefix keyword is necessary to indicate that this implements the prefix form of the √ operator. We could also define another function in the same way but with the postfix keyword. This would take the square root of an operand that came before the √ operator in a statement.

Like any function, it has a name, and this is just the symbol for the operator. The rest of the implementation is just like an ordinary function: A single input parameter is defined of type Double for x, and a return value is defined of type Double. The code in the function makes a call to the Swift square root function, using the value from the input parameter, and then returns the result.

Operator Overloading

To add an additional definition of an operator—and thus overload it–you only have to provide a definition in the same way that was just shown for creating a custom operator.

The difficult part of dealing with operator overloading isn’t writing the code. It is deciding what operators you want to overload and how the functions are defined. You don’t want to overlap definitions or be ambiguous about them. They should also make sense (e.g., see Mattt Thompson’s comment about the addition operator in Chapter 4).

Hands-On Exercises

Go to the following web address with a Macintosh or Windows PC to do the Hands-On Exercises.

For Chapter 25 exercises, go to

understandingswiftprogramming.com/25