Menu
Coddy logo textTech

throws и Error

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

Swift обрабатывает ошибки, заставляя функции объявлять, что они могут завершиться неудачей. Тело функции выбрасывает значение ошибки; вызывающая сторона должна её обработать.

Тип ошибки — это всё, что соответствует встроенному протоколу Error. Самый простой способ объявить свой собственный — использовать перечисление (enum):

enum InputError: Error {
    case empty
    case tooLong
}

Функция, выбрасывающая ошибки, использует ключевое слово throws в своей сигнатуре и инструкцию throw в своем теле:

func validate(_ s: String) throws -> String {
    if s.isEmpty { throw InputError.empty }
    if s.count > 100 { throw InputError.tooLong }
    return s
}

Вы не можете вызвать функцию, выбрасывающую ошибку (throwing function), напрямую; компилятор заставляет вас обработать ошибку. В следующем уроке будет рассказано, как это сделать.

challenge icon

Задание

Легко

Определите перечисление NumError: Error с двумя случаями: negative и tooBig.

Определите функцию, выбрасывающую ошибку, doubleSafely(_ n: Int) throws -> Int, которая:

  • Выбрасывает .negative, когда n < 0
  • Выбрасывает .tooBig, когда n > 100
  • В противном случае возвращает n * 2

Считайте одно целое число из stdin. Вызовите doubleSafely внутри блока do/catch (вы изучите точную форму на следующем уроке; пока используйте этот готовый скелет):

do {
    let result = try doubleSafely(n)
    print("ok: \(result)")
} catch NumError.negative {
    print("negative")
} catch NumError.tooBig {
    print("too big")
} catch {
    print("unknown")
}

Для входного значения 10 вывод будет ok: 20. Для -1negative. Для 500too big.

Шпаргалка

Определите типы ошибок, используя перечисление (enum), соответствующее протоколу Error:

enum InputError: Error {
    case empty
    case tooLong
}

Пометьте функцию как выбрасывающую ошибку с помощью throws и используйте throw для генерации ошибки:

func validate(_ s: String) throws -> String {
    if s.isEmpty { throw InputError.empty }
    if s.count > 100 { throw InputError.tooLong }
    return s
}

Функции, выбрасывающие ошибки, должны вызываться с обработкой ошибок (например, do/catch); компилятор следит за этим.

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

let n = Int(readLine()!)!

// TODO: enum NumError: Error { case negative, tooBig }
// func doubleSafely(_ n: Int) throws -> Int { ... }
// do { let r = try doubleSafely(n); ... } catch NumError.negative { ... } ...
quiz iconПроверьте себя

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

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