Swift Academy · Урок

Автозамыкания

Откладывайте вычисление выражения с помощью @autoclosure.

Урок 4 из 413 шагов

«Автозамыкания» — бесплатный урок Swift Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Swift Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Swift Academy содержит 4 уроков всего.

Что такое autoclosure

@autoclosure автоматически оборачивает выражение аргумента в closure, поэтому оно не вычисляется, пока функция действительно его не использует. Вызывающая сторона передаёт обычное выражение, а не closure.

Без autoclosure

Обычно для отложенного вычисления в месте вызова требуется явный closure:

func logIf(_ cond: Bool, _ message: () -> String) {
    if cond { print(message()) }
}
logIf(true) { "expensive" }  // caller writes braces

С autoclosure

@autoclosure позволяет передать обычное выражение:

func logIf(_ cond: Bool, _ message: @autoclosure () -> String) {
    if cond { print(message()) }
}
logIf(true, "expensive")  // no braces, evaluated only if cond

Доказательство отложенного вычисления

Выражение выполняется только при вызове closure:

func pick(_ cond: Bool, _ value: @autoclosure () -> Int) -> Int {
    cond ? value() : -1
}
func costly() -> Int { print("computed"); return 42 }
print(pick(false, costly()))  // -1  -- "computed" never prints

Где это используется в стандартной библиотеке

Операторы && и ||, assert и ?? используют autoclosures, поэтому правая часть вычисляется только при необходимости.

Раннее завершение, как у ??

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

func orElse<T>(_ value: T?, _ fallback: @autoclosure () -> T) -> T {
    value ?? fallback()
}
func makeDefault() -> Int { print("built"); return 0 }
print(orElse(5, makeDefault()))  // 5  -- "built" never prints

Ленивые сообщения в стиле assert

Создавайте сообщение только при неудачной проверке:

func check(_ cond: Bool, _ msg: @autoclosure () -> String) {
    if !cond { print("FAIL: \(msg())") }
}
check(true, "this is never built")
check(false, "boom")  // FAIL: boom

Autoclosure вместе с escaping

Объединяйте с @escaping, чтобы сохранить отложенное выражение для последующего использования:

var thunks: [() -> Int] = []
func defer2(_ expr: @autoclosure @escaping () -> Int) {
    thunks.append(expr)
}
defer2(1 + 1)
print(thunks[0]())  // 2  -- computed on demand

Более понятный вызов

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

func unless(_ cond: Bool, _ value: @autoclosure () -> String) -> String {
    cond ? "skipped" : value()
}
print(unless(false, "shown"))  // "shown"

Когда НЕ следует это использовать

Autoclosures скрывают тот факт, что аргумент является closure, что может удивить читателей. Используйте их умеренно — только когда отложенное вычисление действительно помогает, например позволяет избежать дорогостоящих значений по умолчанию.

func first<T>(_ a: T?, _ b: @autoclosure () -> T) -> T { a ?? b() }
print(first(nil, 99))  // 99

Autoclosures не принимают аргументов

Autoclosure всегда имеет форму () -> T — он оборачивает одно выражение и не может принимать параметры:

func once(_ make: @autoclosure () -> [Int]) -> Int {
    make().count
}
print(once([1, 2, 3]))  // 3

Быстрая проверка

Что @autoclosure делает с аргументом?

Итоги

Вы узнали об autoclosures:

  • @autoclosure оборачивает выражение аргумента в closure вида () -> T
  • Выражение выполняется только при его вызове функцией — это отложенное вычисление
  • Этот механизм лежит в основе &&, ||, ?? и assert
  • Объединяйте его с @escaping для сохранения; используйте умеренно ради понятности

Курс завершён! Далее: Equatable, Hashable, Comparable.

Можно начать бесплатно

Изучай Swift с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
122
Уроки
409

Часто задаваемые вопросы

Урок «Автозамыкания» бесплатный?

Да — полный текст урока «Автозамыкания» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Swift Academy, подпишись на CoddyKit PRO. Курс Swift Academy содержит 4 уроков всего.

Чему я научусь в уроке «Автозамыкания»?

Откладывайте вычисление выражения с помощью @autoclosure. Ты практикуешь Swift Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Swift Academy?

Предыдущий опыт не требуется. Swift Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Автозамыкания»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Swift Academy?

Да. Каждый урок Swift Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Захват значений по ссылке
  2. Убегающие замыкания
  3. Списки захвата и weak self
  4. Автозамыкания
← Назад к Swift Academy