Что произойдет при анврапе nil значения в опциональной строке в Swift
Что проверяют
Понимаете ли, что принудительное извлечение это не «быстрый способ достать значение», а утверждение «здесь nil невозможен». И знаете ли, чем именно оборачивается нарушенное утверждение.
Как отвечать
String? это тип Optional<String>, перечисление с двумя случаями: .some(String) и .none. Оператор ! берёт значение из .some, а на .none вызывает фатальную ошибку времени выполнения. Приложение падает, в консоли текст вида «Unexpectedly found nil while unwrapping an Optional value».
Важно подчеркнуть: это не исключение. Механизм тот же, что у fatalError и precondition, поэтому do/catch его не перехватит, try? не поможет, процесс просто завершается. Ловить такое в рантайме нечем, лечится только тем, чтобы не доводить до него.
Безопасные способы:
if let s = name { print(s) }
guard let s = name else { return }
let s = name ?? "значение по умолчанию"
let n = name?.count // Int?, цепочка обрывается на nilХороший ответ добавляет, когда ! всё же уместен: когда nil означает поломанный инвариант, например отсутствующий ресурс в бандле, и падение на месте лучше, чем тихая работа с пустотой.
Где спотыкаются
Считают, что ! «разворачивает или даёт пустую строку». Пустой результат даёт ??, а ! даёт либо значение, либо падение, третьего варианта нет.
Второе: не связывают тему с неявно развёрнутыми опционалами. Свойство типа String!, в первую очередь @IBOutlet, падает ровно так же при обращении раньше, чем вью загрузилось, но в коде восклицательного знака на месте использования не видно, и причину ищут долго.
Третье: думают, что удачная проверка действует дальше по коду. Для свойства класса, доступного из нескольких потоков, между if let и следующим обращением значение может стать nil. Поэтому извлечённое значение кладут в локальную константу и работают с ней, а не перечитывают свойство.