Перечислимые типы

b

Для кого написана эта страница

Представленный материал предназначен строго для трёх категорий читателей, каждая из которых преследует свои цели при работе с перечислимыми типами в среде Delphi (Embarcadero Delphi / Object Pascal):

Какие задачи решают перечислимые типы

Для каждой группы цели различаются, поэтому мы разберём их отдельно.

Для начинающих: организация набора констант

Когда вы только осваиваете Delphi, вы сталкиваетесь с проблемой «магических чисел». Вместо кода if State = 0 then вы можете написать if State = TStatus.Active then. Начинающим подходит самый базовый вариант классического перечислимого типа без модификаторов:

type
  TWeekDay = (Monday, Tuesday, Wednesday, Thursday, Friday);
var
  Day: TWeekDay;
begin
  Day := Tuesday;
  case Day of
    Monday: WriteLn('Старт недели');
    Friday: WriteLn('Почти выходные');
  end;
end.

Этот вариант выбирают, когда количество значений не превышает 256 и не требуется дополнительной безопасности на этапе компиляции.

Для корпоративных разработчиков: строгая типизация и защита от ошибок

Крупные проекты страдают от случайного присвоения значений типа «integer» вместо enum. Здесь нужны строго типизированные перечислимые типы с указанием директивы {$SCOPEDENUMS ON} или синтаксис type TMyEnum = (Value1, Value2) <Delphi 2010+>.

Для авторов библиотек: расширяемость и обратная совместимость

Вы пишете компонент, который будут наследовать другие. Если вы добавите новое значение в середину существующего перечисления, то сломаете ord-смещения у всех клиентов. Вам нужен перечислимый тип с явным заданием числовых констант:

type
  TVersionFlag = (
    vfNone  = 0,
    vfAlpha = 1,
    vfBeta  = 2,
    vfRc    = 4,  // резерв для будущих значений
    vfFinal = 8
  );

Для кого это: только для разработчиков, которые распространяют свой код как сторонний пакет. Каждое новое значение должно добавляться как степень двойки, чтобы сочетать флаги через множества (set of).

Как выбрать свой вариант перечислимого типа

  1. Вы начинающий — берите классический enum без скаупинга. Он проще для чтения и не требует настройки компилятора.
  2. Вы пишете средний Win32-проект (до 50 модулей) — включите {$SCOPEDENUMS ON} в начале каждого файла. Это даст автодополнение в IDE и предотвратит случайное использование зарезервированных имён.
  3. Вы разрабатываете FireMonkey-приложение с многопоточностью — обязательно добавьте packed enum, если размер структуры критичен. Но помните: для большинства задач packed не нужен.
  4. Вы хотите, чтобы ваш enum можно было сохранять в INI-файл или JSON — используйте RTTI-функции (TypInfo). Тогда при смене значений потребуется лишь модифицировать перечисление, а строковое представление останется стабильным.
  5. Вы автор библиотеки — каждому значению присвойте явное число, оставляйте зазоры между значениями для будущего расширения и документируйте, что «значения 3,5–7 зарезервированы».

Типичные ошибки по сегментам аудитории

Заключение под ваши задачи

Если вы — новичок, начните с простого: type TDirection = (Left, Right, Up, Down);. Никаких дополнительных настроек не требуется — компилятор Delphi по умолчанию использует классический enum. Код сразу станет читаемее, и вы избежите бинарных констант.
Если вы — разработчик в команде, требуйте от коллег включения {$SCOPEDENUMS ON} в общем репозитории. Это окупится через месяц поддержки.
Если вы — создатель компонентов, используйте явные числовые значения и пишите документацию в комментариях над типом.

Помните: перечислимый тип в Delphi — это не просто синтаксический сахар, а инструмент, который выбирают под реальную аудиторию вашего кода.

Добавлено: 27.04.2026