Функциональные типы в Swift

У каждой функции в Swift есть специальный функциональный тип, состоящий из типов параметров и типа возвращаемого значения.


Такая функция func someFunc(a: Int, b: Int) -> Int {/* ... */} имеет тип (Int, Int) -> Int. Эта запись означает следующее:
"функция с двумя параметрами типа Int, возвращающая значение типа Int".


Эта функция func someFunc() {/* ... */} имеет тип () -> (), т. е. "функция без параметров, которая возвращает Void". Функции, в которых не указано возвращаемое значение, всегда возвращают значение типа Void, эквивалентное в Swift пустому кортежу, который обозначается как ().


В Swift с функциональными типами можно работать так же, как и с другими типами. Например, можно объявить константу или переменную функционального типа и присвоить ей функцию соответствующего типа:



// допустим someFunction и anotherFunction имеют одинаковый тип, тогда корректно следующее выражение
var someFunction: (Int, Int) -> Int = anotherFunction

// теперь функцию someFunction можно вызывать
someFunction(1, 2)


Как и для любого другого типа в Swift, тип функции, присвоенной константе или переменной, проверяется автоматически:



// допустим someFunction и anotherFunction имеют одинаковый тип, тогда корректно следующее выражение
var someFunction = anotherFunction


Функциональные типы наподобие (Int, Int) -> Int могут быть типами параметров другой функции.



func someFunction(nameVarFunction: (Int, Int) -> Int, a: Int, b: Int) {
	// внутри можно использовать функцию nameVarFunction
}

// допустим anotherFunction имеет тип (Int, Int) -> Int, тогда будет корректен следующий вызов функции
someFunction(anotherFunction, 2, 5)


Функциональный тип можно сделать возвращаемым типом другой функции. Для этого нужно записать полный функциональный тип сразу же после результирующей стрелки (->) в возвращаемой функции. В книге The Swift Programming Language представлен следующий пример:



func stepForward(input: Int) -> Int {
    return input + 1
}

func stepBackward(input: Int) -> Int {
    return input - 1
}

func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
	// в зависимости от backwards возвращаем одну из функций
    return backwards ? stepBackward : stepForward
}

var currentValue = 3
let moveNearerToZero = chooseStepFunction(currentValue > 0)
// moveNearerToZero теперь указывает на функцию stepBackward