Menu
Coddy logo textTech

Последующие замыкания

Часть раздела Логика и управление потоком путешествия по Swift на Coddy — урок 39 из 56.

Когда замыкание является последним аргументом функции, вы можете написать его за пределами круглых скобок. Это форма trailing-closure, и именно так код на Swift читается естественно.

let nums = [1, 2, 3]
// Стандартная форма
let a = nums.map({ $0 * 2 })
// Форма с последующим замыканием
let b = nums.map { $0 * 2 }

Если замыкание является единственным аргументом, круглые скобки тоже исчезают. Вот почему всё, что вы видели до сих пор, читается как пользовательская управляющая конструкция.

Вы можете писать свои собственные функции, которые принимают замыкания таким же образом:

func repeatN(_ n: Int, action: () -> Void) {
    for _ in 0..<n {
        action()
    }
}
repeatN(3) {
    print("hi")
}

Форма с замыканием в конце (trailing closure) делает так, что repeatN(3) { ... } читается как встроенный цикл. В этом и заключается суть: управляющие конструкции, которые вы создаете сами, выглядят точно так же, как и те, что входят в стандартную библиотеку.

challenge icon

Задание

Легко

Определите функцию collect, которая:

  • Принимает целое число n и замыкание builder: (Int) -> String
  • Вызывает builder для каждого i от 1 до n (включительно) и возвращает массив результирующих строк

Считайте целое число из stdin, вызовите collect с этим числом, используя замыкание (trailing closure), которое создает "i=<i>" для каждого значения, и выведите объединенный результат через ,.

Для входного значения 4 результатом будет i=1,i=2,i=3,i=4.

Шпаргалка

Синтаксис последующего замыкания: когда замыкание является последним аргументом, его можно написать за пределами круглых скобок. Если это единственный аргумент, круглые скобки опускаются полностью.

let nums = [1, 2, 3]
let a = nums.map({ $0 * 2 }) // стандартный вариант
let b = nums.map { $0 * 2 }  // последующее замыкание

Пользовательские функции могут принимать замыкания таким же образом, благодаря чему они читаются как встроенные управляющие конструкции:

func repeatN(_ n: Int, action: () -> Void) {
    for _ in 0..<n {
        action()
    }
}
repeatN(3) {
    print("hi")
}

Попробуйте сами

let n = Int(readLine()!)!

// TODO: func collect(_ n:Int, builder:(Int)->String) -> [String]
// затем вызовите collect(n) { ... } и выведите результат, объединив через ","
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Логика и управление потоком