- Целые числа
- Вещественные числа
- Символьные типы
- Строковый тип
- Логический тип
- Дата и время
- Цвет
- Перечисления
- Пользовательские перечисления
- Тип void
Пользовательские перечисления
Пользовательские перечисления конструктивно основаны на типе int и принцип их использования полностью совпадает с тем, что было рассказано в предыдущем разделе о встроенных перечислениях. Поэтому мы описываем пользовательские перечисления здесь, хотя они и не являются, строго говоря, встроенными.
Для того чтобы описать собственное перечисление в коде MQL5 используется ключевое слово enum. Простейшая форма описания имеет следующий вид:
enum name
|
Такое определение регистрирует в программе тип перечисления с именем name и указанными в фигурных скобках, через запятую, элементами (их количество ограничено лишь максимальным значением int, что для практических задач можно расценивать как отсутствие ограничений). Идентификаторы element1, element2, element3 можно далее использовать в программе в пределах того контекста, где произведено определение: глобально (т.е. снаружи всех функций) или внутри какой-либо функции (см. раздел Контекст, область видимости и время жизни переменных).
Обратите внимание на точку с запятой после закрывающей скобки. Она нужна, потому что описание перечисления — это отдельная инструкция, а после любой инструкции языка MQL5 необходимо ставить точку с запятой.
Идентификаторы получают по умолчанию константные значения, начиная с 0, каждый следующий — на 1 больше предыдущего. При необходимости программист может задать для каждого элемента конкретное значение, после знака '=' справа от идентификатора. Например, вышеприведенная запись эквивалентна следующей:
enum name
|
В качестве значений допускается указывать только константы или выражения, которые компилятор способен вычислить на стадии компиляции (подробнее об этом — в примере ниже).
Если значения заданы не для всех элементов, то пропущенные значения автоматически вычисляются на основе ближайших известных (предыдущих) путем увеличения на 1. Например,
enum name
|
Здесь первые два элемента получают значения 1 и 2 (вычислено), а начиная с третьего — 10 (указано явно), 11 и 12 (два последних вычислены от 10).
В скрипте TypeUserEnum.mq5 приведено несколько примеров описания пользовательских перечислений.
const int zero = 0; // runtime value is not known at compile time
|
Перечисление INTERNAL демонстрирует возможность описать его внутри функции и тем самым ограничить область видимости/доступности этого типа, что полезно для исключения конфликтов имен.
Перечисление RISK показывает, что можно назначать элементам отрицательные значения. Закомментированный элемент OFF не может быть описан из-за попытки его инициализации неконстантным выражением: в данном случае там указана переменная zero, значение которой компилятор не способен вычислить.
В перечислении INCOME элемент ENORMOUS успешно инициализируется значением из элемента MILLION другого перечисления, определенного выше. Перечисления создаются в момент компиляции и потому доступны в выражениях инициализации.
Перечисление с MILLION не имеет имени — такие перечисления называются анонимными. Их основное применение — декларация констант. Однако чаще для констант все же используются именованные перечисления, так как они позволяют группировать элементы по смыслу.
Поскольку в примере определено 2 перечисления с элементами, имеющими одинаковые имена, указание идентификатора LOW при объявлении переменной x приводит к ошибке компиляции "неоднозначный доступ" ("ambiguous access") — не понятно, элемент какого перечисления имеется в виду. Следует учесть, что идентификаторы могут иметь (и имеют в данном случае) разные значения.
Для разрешения этой проблемы существует специальный оператор контекста — два двоеточия "::". С помощью него формируется полный идентификатор элемента языка, в нашем случае элемента перечисления: сперва указывается имя перечисления, далее оператор "::" и затем идентификатор элемента. Например, RISK::LOW и INCOME::LOW. Позднее мы познакомимся со всеми операторами в соответствующем разделе.