← Назад к вопросам

Что такое throws?

1.8 Middle🔥 281 комментариев
#CI/CD и инструменты разработки#Soft Skills и карьера#SwiftUI

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое throws в Swift

throws — это ключевое слово в Swift, которое указывает, что функция, метод или инициализатор может вызвать ошибку (или «выбросить» её) при выполнении. Это ключевой элемент механизма обработки ошибок в Swift, позволяющий функциям сигнализировать о возникновении проблем без использования альтернативных подходов, таких как опциональные возвращаемые значения или глобальные переменные состояния.

Место в системе обработки ошибок Swift

Swift использует пропагацию ошибок — модель, где ошибки явно передаются (пропагируются) от места возникновения до места обработки. Это отличается от исключений в других языках (например, Java или C++) и является более контролируемым и безопасным подходом.

  • Объявление функции с throws: Чтобы функция могла вызывать ошибку, в её объявлении после параметров добавляется ключевое слово throws.
  • Тип возвращаемого значения: Функция с throws может возвращать любой тип, но её фактический тип становится опциональным с учетом возможности ошибки. Например, функция func fetchData() throws -> String при вызове фактически возвращает String или выбрасывает ошибку.

Использование throws на практике

1. Объявление throwing-функции

enum NetworkError: Error {
    case noConnection
    case serverError(code: Int)
    case timeout
}

func fetchUserData(from url: String) throws -> String {
    // Проверяем условия, которые могут привести к ошибке
    if url.isEmpty {
        throw NetworkError.noConnection
    }
    
    // Если все хорошо, возвращаем результат
    return "User data string"
}

В этом примере:

  • NetworkError — это тип ошибки, соблюдающий протокол Error.
  • Функция fetchUserData объявлена с throws, что означает, что она может не вернуть String, а вместо этого выбросить ошибку типа NetworkError.

2. Вызов throwing-функции

Функцию с throws нельзя вызвать обычным способом — необходимо использовать один из механизмов обработки ошибок:

  • do-catch блок: Самый распространенный способ.
do {
    let data = try fetchUserData(from: "https://api.example.com")
    print("Полученные данные: \(data)")
} catch NetworkError.noConnection {
    print("Ошибка: отсутствует соединение")
} catch NetworkError.serverError(let code) {
    print("Ошибка сервера с кодом: \(code)")
} catch {
    print("Произошла неизвестная ошибка: \(error)")
}
  • try?: Конвертирует результат в опциональное значение. Если ошибка происходит, возвращается nil.
let optionalData = try? fetchUserData(from: "")
// optionalData будет nil, если произошла ошибка
  • try!: Используется, когда вы уверены, что ошибка не произойдет. Если ошибка все же возникает, это вызывает фатальную ошибку выполнения (краш приложения).
let guaranteedData = try! fetchUserData(from: "valid-url")
// Используйте только когда вы абсолютно уверены в успехе

Почему throws важны и как они улучшают код

  1. Ясность и безопасность: Использование throws делает возможность ошибки явной частью сигнатуры функции. Это улучшает читаемость кода и помогает разработчикам быть готовыми к обработке возможных проблем.

  2. Контролируемое распространение ошибок: Ошибки не «просачиваются» незаметно через систему — они должны быть явно обработаны с помощью try, do-catch, или распространены дальше (если текущая функция тоже объявлена с throws).

  3. Интеграция с системой типов: Ошибки в Swift — это просто значения, соблюдающие протокол Error. Это позволяет создавать богатые, типизированные ошибки с дополнительной информацией (коды, сообщения, связанные значения), как показано в примере с NetworkError.

Сравнение с другими подходами

  • Без throws: Можно было бы возвращать опциональное значение (String?) или использовать завершающие колбэки (callbacks) с параметрами ошибки. Однако throws предлагает более стандартизированный, читаемый и интегрированный в язык способ.
  • Отличие от исключений: Swift не использует традиционные исключения, которые могут быть пойманы на любом уровне стека вызовов. throws требует явной обработки ошибок в точках вызова, что снижает риск неожиданных крашей и улучшает управление ресурсами (например, гарантирует выполнение деинициализации).

Рекомендации по использованию

  • Используйте throws для ошибок, которые являются ожидаемой частью работы функции — например, ошибки сети, ошибки парсинга данных, ошибки валидации.
  • Не используйте throws для неожиданных, фатальных ситуаций (например, assertion failures) — для них лучше использовать другие механизмы.
  • Создавайте специализированные типы ошибок (через enum, struct), соблюдающие протокол Error, чтобы предоставлять максимально полезную информацию для обработки.

Таким образом, throws в Swift — это не просто синтаксический элемент, а фундаментальный компонент надежной и понятной архитектуры обработки ошибок, который способствует написанию безопасного и поддерживаемого кода.