Что проверяет where после успешного сопоставления шаблона в Swift?
where выполняет дополнительную проверку после того, как значение уже успешно сопоставлено с шаблоном. Если условие ложно, текущая ветка switch считается неприменимой, и Swift переходит к следующей подходящей ветке.
where не изменяет сам шаблон и не извлекает значение: он фильтрует результаты сопоставления, используя уже связанные переменные.
Pattern matching отделяет две разные операции: распознавание структуры значения и проверку дополнительных ограничений. Шаблон отвечает на вопрос «подходит ли форма значения», а where — «подходит ли оно по дополнительному условию».
Такой подход позволяет не дублировать разбор значения в условии и сохраняет логику сопоставления непосредственно рядом с веткой, которая её обрабатывает.
Одного шаблона часто недостаточно. Например, нужно отличить любое целое число от целого числа, превышающего заданный порог, или извлечь связанное значение перечисления и проверить его содержимое.
Если выполнить такую проверку отдельным вложенным if, код станет более глубоким, а связь между шаблоном и ограничением будет менее очевидной. Если забыть о поведении where, можно ошибочно считать ветку подходящей только потому, что основной шаблон совпал.
Сначала Swift проверяет основной шаблон. Только при успешном совпадении становятся доступны переменные, связанные этим шаблоном; затем вычисляется выражение после where.
В этом примере первый шаблон let number? успешно извлекает число 7, но условие number > 10 ложно. Поэтому первая ветка пропускается, и выполняется вторая.
where может обращаться к переменным, связанным шаблоном. Он не создаёт новые связывания и не заменяет проверку формы значения. Например, условие после шаблона перечисления проверяет связанное значение, но само наличие нужного case определяется шаблоном.
Порядок веток сохраняется: Swift рассматривает их сверху вниз и выбирает первую ветку, у которой совпали шаблон и условие where. Поэтому более узкие условия обычно размещают раньше общих.
Преимущество where — компактное объединение структурного сопоставления и предиката. Ограничение состоит в том, что условие не делает switch исчерпывающим: полнота проверяется по возможным формам значений, а не по истинности произвольных условий where.
Нужно обработать результат поиска: отдельно выделить существующий идентификатор, если он положительный, и отдельно — остальные существующие идентификаторы.
Вариант с общим сопоставлением и вложенным if проще для начинающего кода, но добавляет вложенность и разрывает связь между условием и веткой обработки. Вариант с несколькими case без where требует повторять извлечение значения или писать менее выразительные проверки.
Выбранное решение — шаблон с where: он один раз извлекает значение, проверяет нужное ограничение и оставляет запасную ветку для остальных случаев. В результате структура обработки явно показывает приоритет условий и снижает риск обращения с Optional без предварительного сопоставления.
Вычисляется ли where, если основной шаблон не совпал?
Нет. Сначала проверяется шаблон, и только после его успешного сопоставления Swift вычисляет условие where. Это важно, если предикат использует связанные переменные или потенциально затратную проверку: при несовпадении шаблона такая проверка не выполняется.
Может ли where сделать ветку подходящей для значения другой формы?
Нет. where только отбрасывает уже совпавшие значения. Если шаблон ожидает наличие значения в Optional, условие where не позволит обработать nil; для этого нужна отдельная ветка или другой шаблон.
Делает ли истинный where switch исчерпывающим?
Нет. Компилятор не может считать произвольное условие после where покрывающим все значения соответствующей формы. Даже если предикат логически выглядит полным, обычно требуется другая ветка, например общий шаблон для оставшихся значений, либо default.