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.
Задание
ЛегкоОпределите 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
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Логика и управление потоком
1Строки в деталях
Подсчет и индексыРегистр и удаление пробеловПоиск в строкахРазделение и объединениеЗамена подстрокИтоги — Проверка имени пользователя4Множества
Создание множествОбъединение и пересечениеРазность и симметрическая разностьПодмножество и надмножествоИтоги — Фильтр тегов7Проект — Трекер привычек
Обзор проектаОтметить выполнение10Проект — Движок викторины
Обзор проектаЗадаем вопросы2Диапазоны и шаги
Закрытые и полуоткрытыеШагМетоды диапазоновДиапазоны в SwitchИтоги: Сетка календаря3Словари
Объявление словарейБезопасный поискОбновление словарейИтерация по словарямГруппировка значенийИтоги — Инвентарь6Функции высшего порядка, часть 2
compactMapflatMapsorted(by:)Создание конвейеровПовторение — Таблица лидеров9Обработка ошибок
throws и Errordo, try, catchtry? и try!Проброс ошибокПовторение — Безопасный калькулятор