Каждая функция имеет определенный тип, который складывается из типов параметров функции и типа возвращаемого значения.
Например, пусть у нас есть следующая функция:
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
И затем через эту переменную можно будет обращаться к возвращенной функции.