Условия и ветвление
Программа становится живой, когда умеет принимать решения. В Swift для этого есть if/else, мощный switch и компактный тернарный оператор.
Суть урока: switch в Swift — это не просто замена цепочке if. Он умеет сопоставлять образцы, проверять диапазоны, требует покрыть все случаи и потому исключает забытые ветки.
Начнём с привычного if/else. Условие в Swift обязано быть типа Bool — нельзя написать if 1, как в некоторых языках:
let temperature = 28
if temperature > 30 {
print("Жара")
} else if temperature > 20 {
print("Тепло")
} else {
print("Прохладно")
}Когда вариантов много, на сцену выходит switch. В Swift он гораздо мощнее, чем в C: умеет сопоставлять диапазоны, кортежи, использовать условие where и обязан быть исчерпывающим — покрыть все возможные значения, иначе компилятор не пропустит код:
let score = 87
switch score {
case 90...100:
print("Отлично")
case 70..<90:
print("Хорошо")
case 50..<70:
print("Удовлетворительно")
default:
print("Нужно подтянуть")
}Здесь 90...100 — замкнутый диапазон (включая 100), а 70..<90 — полузамкнутый (до 90, не включая). Ветка default ловит всё остальное и делает switch исчерпывающим. Можно добавить условие через where:
let point = (x: 2, y: 2)
switch point {
case let (x, y) where x == y:
print("На диагонали")
case (let x, 0):
print("На оси X в точке \(x)")
default:
print("Где-то на плоскости")
}Для простого выбора между двумя значениями есть тернарный оператор: условие ? a : b. Например, let label = isOn ? "Вкл" : "Выкл".
Попробуй сам ▶ — запусти код прямо в браузере (Pyodide). Здесь нет Swift, но логика та же, что под капотом мобильного кода:
# Имитируем switch со диапазонами через функцию-классификатор.
def grade(score):
if 90 <= score <= 100:
return 'Отлично'
elif 70 <= score < 90:
return 'Хорошо'
elif 50 <= score < 70:
return 'Удовлетворительно'
else:
return 'Нужно подтянуть'
for s in [95, 87, 61, 30]:
print(s, '->', grade(s))Как работает под капотом
Компилятор анализирует switch на исчерпывающность: для перечислений он проверит, что покрыты все случаи, и без default. Если хоть один случай пропущен, будет ошибка компиляции — именно это делает switch таким безопасным. Для числовых диапазонов компилятор генерирует эффективные сравнения, а сопоставление образцов разбирает кортежи и связывает переменные прямо в case.
Частые ошибки
- Ожидать «провала» (fallthrough) как в C. В Swift case не проваливается в следующий автоматически; для этого есть отдельное ключевое слово fallthrough.
- Неисчерпывающий switch. Без default или без покрытия всех случаев код не скомпилируется.
- Перегружать тернарный оператор. Вложенные тернарники нечитаемы — лучше if/else.
Best practices
- Для перечислений избегайте default — пусть компилятор напомнит про новый случай.
- Используйте диапазоны (...,..<) вместо длинных цепочек сравнений.
- Тернарный оператор — только для коротких, очевидных выборов.
Итоги. if/else подходит для простых развилок, switch — для исчерпывающего разбора множества случаев с сопоставлением образцов, а тернарный оператор — для коротких выборов. Исчерпывающий switch — мощный инструмент безопасности Swift.
Шире контекста
Исчерпывающий switch особенно засияет, когда мы дойдём до перечислений и моделирования состояний экрана. Представьте экран, который может быть в состоянии «загрузка», «успех» или «ошибка». Если вы разбираете эти случаи через switch без default, то в день, когда добавите четвёртое состояние «пусто», компилятор сам подсветит каждое место, где его забыли обработать. Это превращает рефакторинг из источника багов в управляемый процесс: компилятор работает вашим чек-листом. Поэтому опытные разработчики намеренно избегают default для собственных перечислений — они хотят, чтобы язык напоминал о незакрытых случаях. if/else остаётся уместным для простых бинарных развилок, но как только вариантов становится больше двух и каждый требует своей логики, switch с сопоставлением образцов делает код и короче, и безопаснее.