Стендап Сьогодні 📢 Канал в Telegram @stendap_sogodni
🤖🚫 AI-free content. This post is 100% written by a human, as is everything on my blog. Enjoy!01.05.2024
Optional у Swift
Продовжуємо рубрику “аспекти дизайну мов програмування”. Сьогодні не було настрою робити щось по трекеру, тому просто виправляв скарги лінтера. Одна з частих скарг — на так званий “force unwrapping”. Про неї й хочу поговорити.
Відсутність значення у Swift реалізована механізмом Optional. Optional
приймає або значення загорнутого типу, або nil
. Це єдиний випадок, коли звернення до значення неприпустиме, ніякого більше “порожнього посилання” або “непризначеної змінної”. Та головне, що тип Optional обовʼязково потрібно “розгорнути”. Або безпечною перевіркою, або примусово — що може призвести до фатальної помилки.
Мене здивувало у Swift те, скільки методів в стандартній бібліотеці повертають Optional
. Наприклад: методи Array.first, .last, .min, .max
. Бо дійсно, якщо масив порожній, то жодних елементів в ньому не буде. (На жаль, операції з індексами позбавлені такої безпеки та можуть призвести до помилки.)
З наївним написанням умов це трохи дратує: я ж перевірив, що масив не порожній!
if !items.isEmpty {
maxItem = items.max! // Примусово розгортаємо!
// ... щось зробити з maxItem
}
В багатьох випадках таку непряму та тому небезпечну перевірку можна замінити на явну, безпечну:
if let maxItem = items.max {
// ... щось зробити з maxItem
}
Можна помітити зворотний порядок гілок: я звик перевіряти if item == nil
як особливий випадок, а потім вже працювати з ним; у Swift для того є альтернативна конструкція guard
, яка розгортає тип без вкладення:
guard let maxItem = items.max else { return }
// ... щось зробити з maxItem
Взагалі мені дуже подобається такий підхід до відсутності значень, бо він виділяє рівно один механізм та не дозволяє просто його ігнорувати. Проте, якщо в Go надійна програма завжди здобрена перевірками if err != nil
, то у Swift так само багато перевірок guard
.