В switch Swift какой из совпавших шаблонов определяет результат: более специфичный или записанный раньше?
Результат определяет первый совпавший шаблон в порядке сверху вниз. Swift не выбирает автоматически более специфичный шаблон, поэтому общий шаблон, расположенный раньше, может сделать последующие ветки недостижимыми.
Сопоставление с шаблонами используется для компактного разбора перечислений, кортежей, диапазонов и Optional. Последовательный порядок ветвей сохраняет предсказуемость: разработчик явно задаёт приоритет обработки, вместо того чтобы полагаться на неявное сравнение «специфичности» шаблонов.
При пересечении условий легко поместить широкую ветку перед узкой. Тогда значение будет обработано общей веткой, а расположенная ниже проверка никогда не выполнится. Это может скрыть ошибку в обработке Optional, перечисления или результата приведения типа.
Swift проверяет ветви case по порядку. Как только значение удовлетворяет шаблону и его where-условию, выполняется тело этой ветви, а остальные ветви не рассматриваются.
Здесь срабатывает первая ветвь: она проверяет не только наличие значения, но и условие number > 0. Вторая ветвь также подошла бы для 7, однако до неё выполнение не доходит.
Если поменять эти две ветви местами, значение будет обработано как обычное число, потому что шаблон case let number? шире и поглощает все непустые Optional. Компилятор обычно предупреждает о недостижимых ветвях, но полагаться только на предупреждение не следует: сложные шаблоны с where, кортежами и приведением типов могут быть трудны для визуального анализа.
Специфичную проверку обычно располагают раньше общей: сначала конкретные случаи перечисления, диапазоны или дополнительные условия, затем fallback-ветку. Порядок влияет только на выбор ветви; он не изменяет само значение и не выполняет неявное приведение типов.
Представим обработку результата сетевого слоя, представленного как Any: отдельно нужно обработать положительный Int, любое другое число и все остальные значения. Если сначала разместить шаблон для любого Int, положительный Int попадёт в общую ветвь.
Варианты решения:
if — можно явно контролировать проверки, но теряется единая структура взаимоисключающих вариантов;Выбирается третий вариант. В результате положительные числа обрабатываются специальным образом, остальные значения не теряются, а порядок приоритетов виден непосредственно в switch.
Меняется ли порядок ветвей, если у одной из них есть where?
Нет. Условие where проверяется после основного сопоставления с шаблоном, но ветвь всё равно участвует в общем последовательном порядке. Если шаблон совпал, а where вернул false, Swift переходит к следующей ветви.
Может ли более общий шаблон быть полезен перед специфичным?
Да, если он намеренно завершает обработку: например, default или fallback-ветвь может логировать все нераспознанные значения. Но в таком случае последующие ветви недостижимы, поэтому общий шаблон должен быть последним. Иначе программа формально может компилироваться с предупреждением, но требуемая специализированная логика выполняться не будет.
Влияет ли порядок шаблонов на исчерпывающую проверку switch?
Исчерпывающая проверка отвечает на другой вопрос: покрыты ли все возможные значения. Порядок не меняет множество значений, покрытых switch, но может сделать часть ветвей недостижимой. Для Optional обычно требуется отдельно покрыть nil и непустое значение либо использовать default, если детализация вариантов не нужна.