Ответ
Разница заключается в синтаксисе вызова и автоматическом преобразовании выражения в замыкание.
| Аспект | Обычное замыкание | @autoclosure |
|---|---|---|
| Синтаксис передачи | Требует явного указания замыкания { ... }. |
Позволяет передать простое выражение без {}. |
| Цель | Явная передача исполняемого блока кода. | Синтаксический сахар для отложенного вычисления выражений. |
| Вычисление | Может быть как немедленным, так и отложенным (зависит от реализации). | Всегда отложенное — выражение вычисляется только при вызове замыкания внутри функции. |
Сравнение на примере:
// 1. Функция с обычным замыканием
func executeNormal(closure: () -> Bool) {
if closure() { print("Normal: True") }
}
// Вызов ТРЕБУЕТ фигурных скобок
executeNormal(closure: { 2 > 1 })
// 2. Функция с autoclosure
func executeAuto(_ condition: @autoclosure () -> Bool) {
if condition() { print("Auto: True") }
}
// Вызов БЕЗ фигурных скобок — выражение обернуто автоматически
executeAuto(2 > 1)
Практическое применение @autoclosure:
- Оператор объединения по nil (
??): Правый операнд вычисляется только если левый —nil.let value = optionalValue ?? calculateDefault() // calculateDefault() вызовется только если optionalValue == nil - Логические операторы
&&,||: Правый операнд вычисляется только при необходимости (short-circuit evaluation). - Условные проверки (
assert,precondition): Затратные вычисления для отладочных сообщений выполняются только в отладочных конфигурациях.
Итог: @autoclosure — это инструмент для создания более чистого API в случаях, где логика требует передачи выражения для его потенциально отложенного вычисления.