移动(交换)数组
MQL5 能够以一种资源高效的方式来调换两个数组的内容(无需物理分配内存和复制数据)。在某些其它编程语言中,类似的操作不仅支持数组,而且还支持其它变量,这种操作称为移动。
bool ArraySwap(void &array1[], void &array2[])
该函数可调换相同类型的两个动态数组的内容。支持任何类型的数组。但是,该函数不适用于时间序列数组和指标缓冲区,以及具有 const 修饰符的任何数组。
对于多维数组,除第一个维度以外,其他所有维度中的元素数量必须匹配。
如果成功,该函数返回 true,如果出错,则返回 false。
该函数的主要用途是,在已确认不再需要源数组的情况下,避免在传递给函数或从函数返回时对数组进行物理拷贝,从而提高程序的运行速度。事实上,交换几乎是即时完成,因为应用程序数据不以任何方式移动。真正发生交换的是存储在服务结构中的关于数组的元数据(该数据仅占 52 字节),这些结构描述了动态数组。
假设有一个用于通过某种算法处理数组的类。同一数组可能需进行不同操作,因此最好将其保留为类成员。但是问题来了,如何将其传输到一个对象?在 MQL5 中,相关方法(一般来说也就是函数)允许仅通过引用来传递数组。不考虑包含数组并由指针传递的各种包装器类,唯一的简单解决方案似乎就是:例如,在类构造函数中描述数组参数,并使用 ArrayCopy 将其拷贝到内部数组。但使用 ArraySwap 更加高效。
template<typename T>
|
由于在交换之前 array 数组为空,因此在操作之后,用作 source 自变量的数组将变为空,而 array 将被填充输入数据,几乎没有任何开销。
在类的对象成为数组的“所有者”之后,我们可以使用所需的算法修改它,例如,通过特殊方法 process 来修改,该方法将请求的算法的代码作为一个参数。它可能是排序、平滑、混合、添加噪点等等。但是,首先我们尝试使用 ArrayReverse 函数测试关于数组逆反的简单操作概念(参见 ArraySwapSimple.mq5 文件)。
bool process(const int mode)
|
你可以使用两种方法提供对处理结果的访问:逐元素(通过重载 '[]' 运算符),或者通过整个数组(我们再次在对应方法 get 中使用 ArraySwap,但也可以通过 ArrayCopy 提供拷贝方法)。
T operator[](int i)
|
为了通用性,该类被制作为模板。这将允许将来将其改用于任意结构的数组,但在目前,你可以检查 double 类型的简单数组的逆反:
void OnStart()
|
排序任务更现实,对于结构体数组,可能需要按任何字段排序。在 下一章节 我们将详细了解 ArraySort 函数,该函数可让你升序排列任何内置类型的数组,但结构数组除外。届时我们将尝试消除这一“缺口”,让 ArraySwap 实际运行起来。