Swift. Функция в качестве входного и возвращаемого значений
Назад · Оглавление · Дальше
Возвращаемое значение функционального типа
Функция b() возвращает функцию a():
func a() { print("Done!") } func b() -> () -> () { // тип возвращаемого значения () -> () return a } let f = b() // результат функции b() присваивается в константу f // тип данных f неявно определяется как () -> () f() // вызов хранимой в константе функции a() Консоль: Done!
В функцию a() добавляем возвращаемое значение:
func a() -> String { return "Done!" } func b() -> () -> String { // тип возвращаемого значения () -> String return a } let f = b() // константа f хранит функцию a() - результат функции b() a() // "Done!" b() // () -> String f() // "Done!"
Входное значение функционального типа
Функция newWallet передается в качестве входного аргумента функции walletSum:
// Генератор массива банкнот // banknoteCount - требуемое количество банкнот // func newWallet(banknoteCount: Int) -> [Int] { let banknoteTypes = [50, 100, 500, 1000, 5000] var wallet: [Int] = [] for _ in 1...banknoteCount { let index = Int.random(in: 0 ... banknoteTypes.count - 1) wallet.append(banknoteTypes[index]) } return wallet } // Аргумент wallet имеет функциональный тип (Int) -> [Int] // wallet используется для передачи функции newWallet в функцию walletSum // generate - внешнее имя аргумента wallet // func walletSum(generate wallet: (Int) -> [Int]) -> Int? { let n = Int.random(in: 1...10) // количество банкнот let banknotes = wallet(n) // [100, 5000, 50, 5000] var sum = 0 for banknote in banknotes { sum += banknote } return sum } walletSum(generate: newWallet) // 10150
У передаваемой функции указывается только имя, без круглых скобок.
Функция walletSum(generate:) может принять на вход любую функцию с типом (Int) -> [Int], например:
newWallet1000(banknoteCount:) // генератор массива тысячных купюр
Параметры функционального типа для ленивых вычислений
Ленивые вычисления позволяют получить некоторое значение не в момент передачи параметра,
а при попытке доступа к хранящемуся в нем значению.
Рассмотрим три функции:
let n = 1000000 getPiNum(n) // возвращает n-знак после запятой в числе Pi getFibNum(n) // возвращает старшую цифру n-числа в ряду Фибоначчи returnSomeNum(getPiNum(n), getFibNum(n))
Функция returnSomeNum(_:_:) имеет функциональный тип:
(Int, Int) -> Int
Функция принимает на вход два значения, но использует только одно из них, в зависимости от внутренней логики. Ресурсы, задействованные на получение второго числа, тратятся впустую.
Приведем функцию returnSomeNum(_:_:) к типу:
((Int) -> Int, (Int) -> Int)) -> Int
Теперь в returnSomeNum(_:_:) передаются не готовые значения, а функции, которые рассчитывают их.
В теле returnSomeNum будет использована требуемая функция,
а ресурсы на подсчет второго значения затрачены не будут.
Необходимое значение рассчитывается по факту обращения к нему,
а не в момент передачи во входном аргументе.
Назад · Оглавление · Дальше