Иногда самые полезные изменения в языке - не громкие нововведения, а устранение небольших, но раздражающих неудобств. Те, что заставляют писать лишний код, нарушать логику или искать обходные пути. Именно таким изменением стало принятие SE-0493, которое разрешает использовать await внутри defer. На первый взгляд это техническая деталь. На деле - значимое упрощение для написания чистого и надежного асинхронного кода.
Это небольшое, но важное изменение устраняет давнюю проблему: раньше defer не позволял делать await, что мешало писать чистый и надежный асинхронный код для гарантированной очистки ресурсов.
Что изменилось:
Теперь в async-функции вы можете писать так:
func loadData() async throws {
let resource = try await acquireResource()
defer {
await resource.release()
}
try await work(with: resource)
}
Как это работает:
Ключевая механика defer сохраняется, но теперь с поддержкой асинхронности:
🔵Гарантия выполнения: блок defer выполнится при любом выходе из функции (успех, ошибка, возврат).
🔵Ожидание завершения: если внутри defer есть await, функция дождется его завершения, прежде чем вернуть управление.
🔵Ограничение: использовать await в defer можно только внутри async-контекста.
Почему это важно:
Раньше для асинхронной очистки приходилось либо дублировать код на всех путях выхода, либо использовать Task { }, который не гарантировал завершения операции. Теперь очистка ресурсов (закрытие сетевых соединений, сброс состояния, отмена операций) становится такой же простой и надежной, как и в синхронном коде.
🔗 Ссылка на документацию
💡 Вывод:
Принятие SE-0493 - это пример зрелой эволюции языка. Вместо введения сложных новых концепций, Swift устраняет конкретное, давно назревшее несоответствие между синхронными конструкциями языка и его асинхронной парадигмой. Это изменение делает асинхронный код не только безопаснее, но и чище.
➡️ Подписаться на канал
Мобильный трудоголик