Интервальные типы

b

Интервальные типы vs. Перечисления vs. Поддиапазоны: когда что выбирать?

В Delphi существует несколько способов ограничить множество значений переменной. На первый взгляд, интервальные типы (type TDay = 1..31), перечисления (type TWeekDay = (Mon, Tue, Wed)) и поддиапазоны (type TWorkDay = Mon..Fri) решают похожие задачи. Однако за внешним сходством скрываются принципиальные различия в контроле, читаемости и производительности. Ниже — сравнение без общих фраз, только практические различия.

1. Контроль над значениями: жёсткость vs. гибкость

Интервальные типы — единственный способ задать непрерывный диапазон чисел (целых, символьных, логических). Они жёстко фиксируют границы, но не контролируют семантику (значение 15 в диапазоне 1..31 может быть и днём, и номером шага). Перечисления — наоборот, задают дискретный набор имён, компилятор отвергнет любое значение вне списка. Поддиапазоны — промежуточный вариант: они работают на базе перечисления, отсекая часть значений, но всё ещё оперируют осмысленными именами.

Кому подходит: Если вам критично отсечь недопустимые числа (например, день месяца 32) — выбирайте интервальный тип. Если важнее читаемость и исключение логических ошибок (день «32-е» не пройдёт даже на стадии компиляции) — перечисление. Для сокращения большого перечисления (из 50 пунктов оставить 10) — поддиапазон.

Кому не подходит: Интервальный тип бесполезен, когда значения необразуют непрерывный ряд (например, коды ошибок 100, 200, 500). Перечисление неудобно для арифметики (нельзя сложить «Понедельник» + «Вторник» без приведения).

2. Производительность и память: кто экономит?

ХарактеристикаИнтервальный типПеречислениеПоддиапазон
Размер в памяти (default)1–4 байта (автоподбор)1–4 байта (чаще 4)как у базового типа
Проверка на этапе компиляциитолько границылюбое несуществующее имяграницы базового + диапазон
Скорость присвоениямакс (без проверок)макс (без проверок)с проверкой диапазона
Поддержка циклов forдадада (с Succ/Pred)

Кому подходит: Если память критична (встраиваемые системы, огромные массивы) и вы контролируете границы вручную — интервальный тип. Для прототипов и крупномасштабных проектов, где важнее ясность — перечисление.

3. Семантическая нагрузка: как не запутаться?

Главный подвох интервальных типов — числа без контекста. var Day: 1..31 не сообщает, день ли это месяца, номер задачи или температура. При этом вы можете случайно присвоить Day := Day + 300 — ошибка возникнет только в рантайме. Перечисление же сразу говорит: var WeekDay: TDay и WeekDay := Sun — сомнений нет.

Когда интервальный тип становится предпочтительнее: если вы строите математическую модель (например, координаты 0..1023) или работаете с битовыми масками. Для бизнес-логики (статусы заказа, дни недели) однозначно перечисления.

4. Совместимость с существующим кодом

Перечисления в Delphi тесно связаны с WinAPI и VCL (например, TAlign, TScrollStyle). Поддиапазоны часто встречаются в коде работы с датами (диапазоны от 1 до 12 для месяцев). Интервальные типы — выбор для низкоуровневых задач: разбор двоичных протоколов, написание драйверов.

Итог выбор: Если ваш код должен взаимодействовать с системой WinAPI — используйте перечисления. Если вы пишете с нуля парсер данных — интервальный тип. Для сокращения перечисления в существующей модели — поддиапазон.

5. Типичные сценарии (когда что НЕ выбрать)

Итог: стратегия выбора за 1 минуту

Задайте себе два вопроса. Вопрос 1: Мои значения — это осмысленные имена или абстрактные числа? Если имена — перечисление. Если числа — переходите к вопросу 2. Вопрос 2: Нужна ли проверка на компиляции для отсечения недопустимых чисел? Если да — интервальный тип. Если приоритет — читаемость и документация — перечисление с константами. Поддиапазон — только если вам нужно отрезать часть уже существующего перечисления, не меняя его логику. Не пытайтесь использовать интервальный тип для имитации перечисления — это путь к багам.

Добавлено: 27.04.2026