Каждая функция имеет определенный тип, который складывается из типов параметров функции и типа возвращаемого значения.
Например, пусть у нас есть следующая функция:
func sum(_ x: Int, _ y: Int) -> Int{
return x + y
}
Эта функция имеет тип (Int, Int) -> Int
Или, например, функция:
func printName(name: String){
print(name)
}
Она имеет тип (String) -> Void
Используя тип функции, мы можем определять переменные или константы этого типа и затем динамически назначать их конкретные функции:
func sum(_ a: Int, _ b: Int) -> Int{
return a + b
}
func subtract(_ a: Int, _ b: Int) -> Int{
return a - b
}
var someFunc: (Int, Int) -> Int
someFunc = sum
print(someFunc(5, 4)) // 9
someFunc = subtract
print(someFunc(5, 4)) // 1
Итак, здесь у нам определены две функции sum и subtract, которые имеют одни и те же параметры и возвращаемые типы значений, но отличаются конкретными действиями: в одном случае идет сложение, а в другом - вычитание чисел.
Также определена переменная someFunc, которая имеет тип - функцию с двумя параметрами типа Int и возвращаемым значением типа Int. То есть
переменная someFunc по параметрам и возвращаемому типу соответствует функциям sum и subtract. Поэтому мы можем динамически приравнять переменную одной из функций
и вызвать ее:
someFunc = sum print(someFunc(5, 4)) // 9
Фактически здесь будет вызываться функция sum. Поэтому в качестве результата мы получим сумму 4 + 5.
Затем динамически мы можем приравнять переменную другой функции:
someFunc = subtract var result = someFunc(5, 4) // 1
Подобная функциональность открывает нам большие возможности. В частности, мы можем использовать типы функций в качестве типов параметров или в качестве возвращаемых типов в других функциях.
func sum(_ a: Int, _ b: Int) -> Int{
return a + b
}
func subtract(_ a: Int, _ b: Int) -> Int{
return a - b
}
func getResult(_ binaryFunc: (Int, Int) -> Int, _ a: Int, _ b: Int){
let result = binaryFunc(a, b)
print(result)
}
getResult(sum, 13, 10) // 23
getResult(subtract, 12, 8) // 4
Здесь функция getResult в качестве первого параметра принимает функцию. Типу этого параметры соответствуют выше определенные функции sum и substract,
поэтому они могут использоваться при вызове функции getResult:
getResult(sum, 13, 10)
func add(_ x: Int, _ y: Int) -> Int {return x + y}
func subtract(_ x: Int, _ y: Int) -> Int {return x - y}
func multiply(_ x: Int, _ y: Int) -> Int {return x * y}
func select (_ n: Int) -> (Int, Int) -> Int{
switch n {
case 2:
return subtract
case 3:
return multiply
default:
return add
}
}
let x = 12, y = 8
var someFunc = select(1) // add
print(someFunc(x, y)) // 20
someFunc = select(2) // subtract
print(someFunc(x, y)) // 4
someFunc = select(3) // multiply
print(someFunc(x, y)) // 96
Возвращаемым типом функции select является тип (Int, Int) -> Int. Это значит, что
select должна возвратить функцию, которая принимает два параметра типа Int и возвращает значение типа Int.
Под это определение подходят функции sum, multiply и subtract.
Поэтому в select мы возвращаем не конкретное значение, а одну из этих функций в зависимости от значения параметра n.
Возвращаемый результат мы можем присвоить переменной или константе:
var someFunc = select(1) // add
И затем через эту переменную можно будет обращаться к возвращенной функции.