枚举
枚举是 MQL5 中内置的一组类型,每个枚举都包含一组命名常量来描述相关的概念或特性。这些常量也称为枚举元素。
例如,ENUM_DAY_OF_WEEK 枚举包含表示一周中所有天数的常量:
标识符 (ID) |
说明 |
值 |
---|---|---|
SUNDAY |
星期日 |
0 |
MONDAY |
星期一 |
1 |
TUESDAY |
星期二 |
2 |
WEDNESDAY |
星期三 |
3 |
THURSDAY |
星期四 |
4 |
FRIDAY |
星期五 |
5 |
SATURDAY |
星期六 |
6 |
ENUM_ORDER_TYPE 枚举描述了 MetaTrader 5 中支持的所有订单类型:
标识符 (ID) |
说明 |
值 |
---|---|---|
ORDER_TYPE_BUY |
市场买入订单 |
0 |
ORDER_TYPE_SELL |
市场卖出订单 |
1 |
ORDER_TYPE_BUY_LIMIT |
限价买入挂单 |
2 |
ORDER_TYPE_SELL_LIMIT |
限价卖出挂单 |
3 |
ORDER_TYPE_BUY_STOP |
买入止损挂单 |
4 |
ORDER_TYPE_SELL_STOP |
卖出止损挂单 |
5 |
ORDER_TYPE_BUY_STOP_LIMIT |
达到订单价格后,限价买入挂单会以限价止损价格成交 |
6 |
ORDER_TYPE_SELL_STOP_LIMIT |
达到订单价格后,限价卖出挂单会以限价止损价格成交 |
7 |
ORDER_TYPE_CLOSE_BY |
通过反向头寸平仓的指令 |
8 |
有几十种不同枚举。枚举的名称以 "ENUM_" 为前缀。我们将在接触到相关领域时学习这些枚举。
每个枚举都是独立的类型。但它们的内部表示是相同的,即四字节整数 (int)。每个枚举常量都被编码为一个特定数字,但在大多数情况下,程序员无需记住这些数字,因为使用枚举的主要目的就是用明显的标识符替换内部表示。
编译器确保枚举值始终是其中一个重新定义常量。否则,将出现警告或编译错误(具体请参见示例)。
这是 ENUM_DAY_OF_WEEK 枚举的底层表示形式(MQL5/Scripts/MQL5Book/p2/TypeEnum.mq5 脚本)。
void OnStart()
|
表示一周内日期的所有常量被编码为数字 0 到 6,以星期日为起点。原则上说,常量不一定是连续数字,也不一定从 0 开始。某些枚举中就不是这样。
请注意,相同常量在不同枚举类型中可能代表不同含义。例如,对于 ENUM_ORDER_TYPE 枚举中的 ORDER_TYPE_BUY 和 ORDER_TYPE_SELL 订单,ENUM_DAY_OF_WEEK 中的 SUNDAY 和 MONDAY(表示一周内的日期)具有相同的值(0 和 1)。
把简单整数变量 i 的值拷贝到枚举变量 x 时,编译器会给出一个警告,因为在程序执行阶段,变量 i 中可能包含不允许的常量值。
在变量 y中,我们获取数字 1(表示 MONDAY),编译器认为这是一个正确的操作。
如果尝试将一个枚举的常量写入另一个枚举的变量(如上例中将 MONDAY 写入 type 变量)可能会导致有关隐式类型转换的警告。如果正在写入的常量与某个目标枚举元素的值相同,就会发生这种情况。也就是说,这两个枚举各自有一个具有相关值的元素。然后,编译器代替程序员自动执行隐式转换,但会显示一个警告,提醒程序员检查是否一切正常:实际上,用 ORDER_TYPE_SELL 替代 MONDAY 确实很怪异;但为了进行演示,我们故意这么做了。
如果被拷贝的元素的值与另一个枚举的任何元素都不匹配(例如将 ORDER_TYPE_CLOSE_BY 写入 day 变量中),则会生成编译错误,因为隐式转换无法完成。
带有 z 变量的注释字符串也会导致编译错误,因为 ENUM_DAY_OF_WEEK 不包含值 10。如果程序员确信,在特殊情况下,仍然需要在枚举类型变量中获取随机值,则可以使用显式类型强制转换。
显式和隐式类型强制转换将在 类型强制转换一节中讨论。
MQL5 允许程序员使用 enum 关键字来声明自己应用的枚举。这个特性将在下一节 自定义枚举 (enum) 中说明。