Как реализовать метод с проверкой максимальной скорости и обработкой ошибки в Swift?
Что проверяют
Знаете ли вы модель ошибок Swift: как объявить свою ошибку, где уместен throws, а где хватит опционала или precondition. Следом обычно просят показать вызов с разными catch и спрашивают про разницу между try? и try!.
Как отвечать
Модель задачи: у структуры Car есть maxSpeed и mutating func setSpeed(_ value: Double) throws. Каркас ответа:
- тип ошибки:
enum SpeedError: Errorс кейсамиnegative,notFiniteиexceedsLimit(requested: Double, limit: Double). Ассоциированные значения несут контекст, который понадобится в сообщении или логе; - проверки: цепочка
guard value.isFinite else { throw SpeedError.notFinite }, затем проверка на отрицательное значение и на превышение лимита.guardдержит основной путь без вложенности, а присваивание идёт только после всех проверок, поэтому объект не остаётся в полуизменённом состоянии; - сообщение для пользователя: соответствие
LocalizedErrorсerrorDescription, тогда ошибку можно сразу показать вalert; - вызов:
do { try car.setSpeed(120) } catch SpeedError.exceedsLimit(let requested, let limit) { ... } catch { ... }. Без общегоcatchкод не скомпилируется, если внешняя функция сама не объявленаthrows.
В Swift 6 появились типизированные ошибки: func setSpeed(_ value: Double) throws(SpeedError). Тип ошибки становится частью сигнатуры, и вызывающему не нужно гадать, что может прилететь. Применяют их точечно, там, где набор ошибок действительно закрыт. Стоит упомянуть, что сеттер свойства бросать ошибку не умеет, поэтому валидацию с throws делают методом, а не через didSet. Где спотыкаются
Используют try! в рабочем коде. Превышение скорости это ожидаемая ситуация, а try! превращает её в падение приложения.
Глушат ошибку через try? и не обрабатывают nil. Пользователь не понимает, почему значение не применилось, а в логах пусто.
Путают ошибку и нарушение контракта. Если отрицательная скорость означает баг в вызывающем коде, честнее precondition, а throws стоит оставить для ситуаций, которые вызывающий может осмысленно обработать.