Menu
Coddy logo textTech

try? и try!

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

Иногда вам не важно, какую именно ошибку выбросила функция, вам просто нужен результат или запасной вариант. Swift предлагает две краткие формы.

try? превращает любую выброшенную ошибку в nil. Результатом является Optional от типа возвращаемого значения функции:

enum E: Error { case nope }
func risky() throws -> Int { throw E.nope }

let result = try? risky()        // nil
let safe   = (try? risky()) ?? 0 // 0

Используйте его в паре с ?? для задания значения по умолчанию. Это самый короткий вариант фразы «вызови это и дай мне результат в любом случае».

try! говорит: «Я знаю, что это не вызовет ошибку». Если это произойдет, ваша программа завершится с ошибкой. Используйте его только тогда, когда можете доказать, что вызов безопасен; в повседневном коде отдавайте предпочтение try? с запасным вариантом или полноценному блоку do/catch.

challenge icon

Задание

Легко

Определите NumError: Error с одним случаем bad. Определите выбрасывающую ошибку функцию parseEven(_ s: String) throws -> Int, которая:

  • Выбрасывает .bad, когда s не может быть преобразовано в Int или когда полученное значение нечетное
  • В противном случае возвращает полученное целое число

Прочитайте одну строку ввода: список строк, разделенных запятыми. Для каждой из них используйте try? вместе с ?? -1, чтобы получить либо обработанное четное целое число, либо -1.

Выведите по порядку полученные целые числа, разделенные ,. Затем на второй строке выведите количество значений, которые вернулись как -1.

Для входных данных 4,7,abc,8,11,2 результатом будет:

4,-1,-1,8,-1,2
3

Шпаргалка

try? преобразует выброшенную ошибку в nil, возвращая Optional:

let result = try? risky()        // nil при ошибке
let safe   = (try? risky()) ?? 0 // резервное значение

try! вызывает аварийное завершение (crash), если вызов выбрасывает ошибку — используйте только тогда, когда вызов гарантированно безопасен:

let value = try! guaranteedSafe()

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

let parts = readLine()!.components(separatedBy: ",")

// TODO: enum NumError; func parseEven(_:) throws -> Int;
// для каждой части, (try? parseEven(part)) ?? -1
quiz iconПроверьте себя

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

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