В этом фрагменте определите, почему условие с диапазоном совпадает со значением и какой текст напечатает ко...

В этом фрагменте определите, почему условие с диапазоном совпадает со значением и какой текст напечатает код:

let statusCode = 404

if case 400..<500 = statusCode {
    print("ошибка клиента")
} else {
    print("другой результат")
}
Проходите собеседования с ИИ помощником Hintsage

Краткий ответ

Код напечатает ошибка клиента. Запись 400..<500 в pattern matching проверяет, входит ли statusCode в диапазон от 400 включительно до 500 исключительно.

Swift выполняет эту проверку через оператор сопоставления шаблона ~=: для диапазона он определяет, принадлежит ли значение заданному диапазону.

Исторический контекст

Pattern matching нужен для компактного описания условий, связанных со структурой или диапазоном значения. Такой подход позволяет использовать один механизм в switch и в условии if case, не дублируя сравнения вроде statusCode >= 400 && statusCode < 500.

В Swift диапазон — это не только способ создать последовательность значений. Он также может выступать шаблоном, с которым сопоставляется другое значение.

Постановка проблемы

При обработке HTTP-кодов важно не перепутать границы диапазона. Код 400 должен попасть в категорию ошибок клиента, а код 500 — нет.

Если заменить полуоткрытый диапазон 400..<500 на закрытый 400...500, значение 500 будет ошибочно классифицировано как ошибка клиента. Если использовать только statusCode / 100, можно потерять точность для нестандартных кодов и усложнить условие.

Подробное решение

Конструкция if case pattern = value пытается сопоставить значение с шаблоном. В данном случае шаблон — диапазон 400..<500, а сопоставляемое значение — целое число 404.

Для диапазона применяется оператор ~=. Концептуально проверка эквивалентна следующему условию:

let statusCode = 404 if statusCode >= 400 && statusCode < 500 { print("ошибка клиента") }

Разница в том, что if case использует общий механизм сопоставления шаблонов и хорошо сочетается с другими шаблонами Swift. Оператор ..< создаёт полуоткрытый диапазон: левая граница включается, правая исключается. Поэтому 404 совпадает, 400 совпадает, а 500 — нет.

Это не приведение типа и не проверка равенства диапазона числу. Диапазон выступает шаблоном, а конкретное поведение сопоставления определяется ~= для соответствующих типов.

Ситуация из практики

В сетевом клиенте нужно разделить ответы на успешные, ошибки клиента и ошибки сервера. Возможны три варианта.

Первый — цепочка сравнений:

if code >= 200 && code < 300 { /* успех */ } else if code >= 400 && code < 500 { /* клиент */ } else if code >= 500 { /* сервер */ }

Плюс этого решения — явность. Минус — границы и логика быстро становятся громоздкими при добавлении новых категорий.

Второй — вычисление группы через деление на 100. Это коротко для стандартных HTTP-кодов, но хуже выражает нестандартные диапазоны и отдельные исключения.

Третий — switch с диапазонами:

switch code { case 200..<300: print("успех") case 400..<500: print("ошибка клиента") case 500..<600: print("ошибка сервера") default: print("неизвестный код") }

Для нескольких взаимоисключающих категорий выбран третий вариант: диапазоны явно показывают границы, а default обрабатывает значения вне известных интервалов. Для единственной проверки достаточно if case.

Что кандидаты часто упускают

  1. Вопрос: Включается ли правая граница в шаблон 400..<500?

    Ответ: Нет. Оператор ..< создаёт полуоткрытый диапазон: 400 включён, 500 исключён. Поэтому 499 совпадает с шаблоном, а 500 — нет. Для включения обеих границ используется 400...500.

  2. Вопрос: Чем if case 400..<500 = code отличается от обычного if code == 400..<500?

    Ответ: Эти выражения имеют разный смысл и типы. Число нельзя сравнить на равенство с диапазоном: диапазон описывает множество допустимых значений, а не одно значение. if case применяет механизм pattern matching и проверяет принадлежность code диапазону через ~=.

  3. Вопрос: Можно ли использовать собственный тип как шаблон для if case?

    Ответ: Да, если для подходящих типов доступен оператор ~=. Например, можно определить собственную функцию сопоставления для шаблона и значения, после чего использовать этот шаблон в switch или if case. Это расширяет выразительность pattern matching, но требует аккуратно проектировать семантику сопоставления: результат должен быть предсказуемым, а проверка — не иметь неожидательных побочных эффектов.