Совсем недавно я боялся "Замыканий". Я избегал их как можно чаще. Эти фигурные скобки и странно выглядящие слова, такие как in, completHandler, @escaping казались сложными и непреодолимыми. 😶

Если вы не знакомы с замыканиями, не думайте волноваться. Я расскажу о них. Тем не менее я ожидаю, что мои читатели поймут, что значит вернуть значение с помощью функции. Если нет, то вы можете начать с уроков YouTube по основным материалам и вернуться после.

Источник

Swift 3 Tutorial with Bob (YouTube)

Мотивация

Функциональное программирование это тенденция в iOS и замыкание связано с этим. Какие? Зачем? Как? Ну, я думаю, мы слишком рано обсуждаем отношения между ними. Надеюсь, я смогу сделать настоящий плавный переход во второй части.

Я думаю, что вы научитесь

Замыкания — функция более высокого порядка, функция первого класса. Эти слова вы, может, слышали? Ну, давайте разбираться вместе.

Что такое замыкание?

Когда я объясняю это своей 13-летней сестре, я просто говорю, что это функция без ключевого слова func и без её имени. Однако с точки зрения новичков замыкания выглядят неполными.

Итак, давайте сравним, как мы бы добавили два числа в function и closure. Оба будут принимать два параметра Int и возвращать один Int. Начнем с функции.

func addTwoNumbers(number1: Int, number2: Int) -> Int {
 return number1 + number2
}
var storedFunc = addTwoNumbers
storedFunc(5, 9) // 14

Я сохранил функцию addTwoNumber во вновь созданной переменной var = storedFunc. Но как это возможно? Ну, в Swift 3, как и многие другие языки программирования, функции Swift описываются как функция первого класса. Я не знаю, почему это называется так, но вы можете сохранить функцию переменной или константой.

Однако для хранения функции нам не нужно использовать ключевое слово func. Действительно, вместо этого мы можем использовать замыкание.

var storedClosure: (Int, Int) -> Int = { (number1, number2) in
 return number1 + number2
}
storedClosure(number1: 5, number2: 9) // 14

Вышеприведенный пример идентичен первому примеру. Ключевое слово in используется для разделения входных параметров, number1 и number2 от return. Кроме того, мы заявили, что тип storedClosure (Int, Int) -> Int. Предписанный тип сообщает переменной, что он принимает два параметра и возвращает один Int.

Надеюсь, к настоящему моменту вы поняли, что замыкание - это функция без имени и ключевого слова func. Или вы можете сказать, что функция - это еще одно подробное замыкание. 🤔

Но приведенный выше пример можно упростить, и, да, он по-прежнему называется замыканием.

// Shorter
var storedClosure: (Int, Int) -> Int = { return $0 + $1 }

// Super Short
var storedClosure: (Int, Int) -> Int = { $0 + $1 }

Итак, что это за $0 и $1? Ну, это просто синтаксис Swift. Он автоматически распознает два параметра Int. Первое значение ввода — $0, а второе — $1. Кроме того, нам даже не нужно возвращать результат, если вы просто играете с этими двумя параметрами.

var storedClosure: (Int, Int) -> Int = { (number1, number2) in
 print("Hello")
 return number1 + number2

}
storedClosure(3, 5) // "Hello"

Кстати, если вы не слишком уверены, что происходит, вы можете проверить мое видео на YouTube. Я говорю по-английски.

И напоследок

До этих пор вы знали, что function и closure практически одинаковы, и обе являются первоклассными, поскольку вы можете хранить их в переменной. Но также они называются функцией высшего порядка. Какие? (Опять же, я не знаю, откуда взялось это название). Вы можете использовать function и closure в качестве параметров и даже вернуть их.

Например, вы можете вставить функцию в функцию. Попробуем вставить функцию print, которая возвращает «hello world» внутри функции. Тип функции, используемой в качестве параметра, - () -> String.

func insertSomething(closure: () -> String) {
 closure()
}

Хорошо, пришло время добавить функцию, возвращающую «Hello World».

func returnHelloWorld() -> String {
 print("Hello World")
 return "Hello World"
}

Теперь вызовите её.

insertSomething(closure: returnHelloWorld) // "Hello World"

Для того, чтобы повторить, вы вставили returnHelloWorld, которая является функцией и возвращает строковое значение в insertSomething. Если вы хотите сразу добавить замыкание в качестве параметра, то вы можете сделать это.

var closureHelloWorld: () -> String = { return "hello" }

insertSomething(closure: closureHelloWorld) // "hello"

Если вы просто хотите что-то добавить сразу, то вы можете сделать это.

insertSomething(closure: { return "hello world"}) // "hello world"

Ссылка на оригинал: No Fear Closure in Swift 4 with Bob

Автор: Bob Lee