Как разворачивать опционалы в Swift?
Что проверяют
Знаете ли вы весь набор способов, а не только if let, и умеете ли выбрать подходящий под ситуацию. Следом обычно спрашивают, когда допустим ! и чем guard let отличается от if let по области видимости.
Как отвечать
Опционал в Swift это enum Optional<Wrapped> с кейсами .some(value) и .none, поэтому все способы сводятся к проверке кейса:
if let: значение доступно только внутри блока. Начиная со Swift 5.7 есть короткая записьif let user { ... }без повторения имени;guard let: ранний выход, если значения нет, а развёрнутая константа живёт до конца функции. Веткаelseобязана покинуть скоуп черезreturn,throwилиbreak;??: значение по умолчанию. Правая часть вычисляется лениво, через autoclosure;- optional chaining:
user?.address?.cityвернёт опционал, даже еслиcityобъявлен неопциональным; mapиflatMap: преобразовать значение без ручного разворачивания, аcompactMapвыкинетnilиз коллекции;switchи паттерны:case let value?илиcase .some(let value), удобно, когда нужно разобрать несколько опционалов сразу;!: принудительное разворачивание, приnilприложение падает. Уместно там, гдеnilозначает ошибку программиста, и лучше с понятным сообщением черезguard ... else { fatalError("...") }.
Упомяните неявно развёрнутые опционалы String!: они остались в основном у @IBOutlet и ведут себя как ! при каждом обращении.
Где спотыкаются
Ставят ! везде, где ругается компилятор. На ревью это читается как незнание, а в проде превращается в краш на первых же пустых данных с сервера.
Путают области видимости: пытаются использовать константу из if let после блока или пишут guard без выхода в else, и код не компилируется.
Забывают, что try? тоже даёт опционал. Начиная со Swift 5 вложенные опционалы от try? схлопываются в один уровень, а в старых примерах до сих пор разбирают String??.