First, let's reiterate what a function type is:
var sum: (Int, Int) -> Int
The type of sum
is a function that takes two Int
values and returns one Int
value. We can assign both functions and closures to it, as they are essentially the same thing:
func sumFunction(a: Int, b: Int) -> Int { return a + b } let sumClosure = {(a: Int, b: Int) in return a + b} sum = sumFunction sum = sumClosure
We can also assign an operator to it:
sum = (+)
This is because an operator is a function (the parentheses around the + operator are just to signal that we want to use it as a function, not add things together right away). The definition of the +
operator for Int
is:
static func +(lhs: Int, rhs: Int) -> Int
So, whenever a function has a parameter of a function type, we can supply an operator, as long as the input and output match:
func perform(operation: (Int, Int) -> Int, on a: Int, _ b: Int) -> Int { return operation(a,b) } perform(operation: +, on: 1, 2)
Initialisers can also be used as functions:
extension Int { init(add a: Int, _ b: Int) { self.init(a + b) } } sum = Int.init perform(operation: Int.init, on: 2, 3)
We have to use .init
to show that we are referring to an initialiser, not the type Int
itself.
If several functions have the same name, or initialisers have the same number and types of arguments, we can specify which one we are referring to by including the argument labels. Here are the full names of the preceding functions:
sumFunction(a:b:) perform(operation:on:_:) Int.init(add:_:)