枚举

在 MQL5 API 中,可使用 EnumToString 函数将枚举值转换为字符串。没有现成的逆转换。

string EnumToString(enum value)

该函数将任何类型的枚举的值(即传递元素的 ID)转换为字符串。

我们使用该函数来解决最常见的任务之一:找出枚举大小(其包含多少个元素)以及所有元素准确对应的值。为此,在头文件 EnumToArray.mqh 中,我们实现特殊 模板函数 (由于模板类型为 E,因此适用于任何枚举):

template<typename E>
int EnumToArray(E dummyint &values[],
   const int start = INT_MIN
   const int stop = INT_MAX)
{
   const static string t = "::";
   
   ArrayResize(values0);
   int count = 0;
   
   for(int i = starti < stop && !IsStopped(); i++)
   {
      E e = (E)i;
      if(StringFind(EnumToString(e), t) == -1)
      {
         ArrayResize(valuescount + 1);
         values[count++] = i;
      }
   }
   return count;
}

其运算概念基于以下原理。由于 MQL5 中的枚举存储为 int 类型的整数,支持将任何枚举隐式强制转换为 (int),同时也允许将 int 隐式强制转换为任何枚举类型。在此情况下,如果值对应于枚举的某个元素,则 EnumToString 函数返回一个带有该元素 ID 的字符串。否则,该函数返回一个 ENUM_TYPE::value 格式的字符串。

因此,通过在可接受范围内的整数之间循环并将这些整数显式强制转换为一种枚举类型,即可分析输出字符串 EnumToString 中是否存在 '::',以确定给定整数是否是枚举成员。

与其它字符串函数一样,此处使用的 StringFind 函数将在 下一章中讲解。

我们创建 ConversionEnum.mq5 脚本以测试概念。在脚本中,我们实现辅助函数 process,该函数将调用 EnumToArray 模板,报告枚举中元素的数量,并打印生成的数组(其中包含枚举元素的值匹配的项)。

template<typename E>
void process(E a)
{
  int result[];
  int n = EnumToArray(aresult0USHORT_MAX);
  Print(typename(E), " Count="n);
  for(int i = 0i < ni++)
  {
    Print(i" "EnumToString((E)result[i]), "="result[i]);
  }
}

为了研究枚举,我们将使用具有 ENUM_APPLIED_PRICE 价格类型的内置枚举。在 OnStart 函数内,我们首先确保 EnumToString 生成如上所述的字符串。因此,对于元素 PRICE_CLOSE,函数将返回字符串 "PRICE_CLOSE",而对于明显超出范围的值 (ENUM_APPLIED_PRICE)10,则将返回 "ENUM_APPLIED_PRICE::10"。

void OnStart()
{
   PRT(EnumToString(PRICE_CLOSE));            // PRICE_CLOSE
   PRT(EnumToString((ENUM_APPLIED_PRICE)10)); // ENUM_APPLIED_PRICE::10
   
   process((ENUM_APPLIED_PRICE)0);
}

接下来,我们调用函数 process 以将任何值强制转换为 ENUM_APPLIED_PRICE(或该类型的变量)并且获得以下结果:

ENUM_APPLIED_PRICE Count=7
0 PRICE_CLOSE=1
1 PRICE_OPEN=2
2 PRICE_HIGH=3
3 PRICE_LOW=4
4 PRICE_MEDIAN=5
5 PRICE_TYPICAL=6
6 PRICE_WEIGHTED=7

我们看到枚举中定义了 7 个元素,并且编号不是从通常的 0 开始,而是从 1 (PRICE_CLOSE) 开始。了解与元素关联的值在某些情况下可优化算法编写。