Ответ вслух Middle Опционалы обновлено

Force unwrap в продакшен-коде: политика команды

Вопрос

В код-ревью вы видите ! в нескольких местах. Как вы решаете, оставить или переписать?

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

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

Показать ответ и разбор

Коротко

Я смотрю, откуда берётся значение. Если это данные извне: ответ сервера, ввод пользователя, файл на диске, то ! недопустим, там нужен guard let с обработкой или ошибка наверх.

Что должно прозвучать в ответе

  • `!` допустим, только если `nil` означает ошибку программиста, а не данных

  • Данные извне (сеть, пользователь, диск) распаковываются безопасно

  • Вместо `!` для инвариантов можно `guard ... else { preconditionFailure("причина") }`

  • Линтер (SwiftLint `force_unwrapping`) и исключения с комментарием

  • Крэш лучше скрытого некорректного состояния, но хуже обработанной ошибки

Что могут спросить следом

  • Чем precondition отличается от assert в релизной сборке?
  • Как вы относитесь к try!?

Разбор

Я смотрю, откуда берётся значение. Если это данные извне: ответ сервера, ввод пользователя, файл на диске, то ! недопустим, там нужен guard let с обработкой или ошибка наверх. Если nil невозможен по построению, например URL(string: "https://example.com") из литерала или ресурс из бандла, ! можно оставить, но лучше явно: guard let ... else { preconditionFailure("нет ресурса X") }, тогда в логе крэша будет понятная причина. В команде это закрепляется линтером: правило force unwrapping включено, исключения с комментарием. Логика такая: крэш на нарушенном инварианте лучше тихого неправильного поведения, но всё, что может прийти извне, обязано обрабатываться.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.

Термины по теме