Các phép liệt kê
Enumerations là một nhóm các kiểu được xây dựng trong MQL5, mỗi kiểu chứa một tập hợp các hằng số được đặt tên để mô tả các khái niệm hoặc thuộc tính liên quan. Các hằng số này cũng được gọi là các phần tử enumeration.
Ví dụ, kiểu liệt kê ENUM_DAY_OF_WEEK
chứa các hằng số cho tất cả các ngày trong tuần:
Mã định danh (ID) | Sự miêu tả | Giá trị |
---|---|---|
SUNDAY | Sunday | 0 |
MONDAY | Monday | 1 |
TUESDAY | Tuesday | 2 |
WEDNESDAY | Wednesday | 3 |
THURSDAY | Thursday | 4 |
FRIDAY | Friday | 5 |
SATURDAY | Saturday | 6 |
Enumeration ENUM_ORDER_TYPE
mô tả tất cả các loại lệnh được hỗ trợ trong MetaTrader 5:
Mã định danh (ID) | Sự miêu tả | Giá trị |
---|---|---|
ORDER_TYPE_BUY | Lệnh mua thị trường | 0 |
ORDER_TYPE_SELL | Lệnh bán thị trường | 1 |
ORDER_TYPE_BUY_LIMIT | Lệnh chờ mua giới hạn | 2 |
ORDER_TYPE_SELL_LIMIT | Lệnh chờ bán giới hạn | 3 |
ORDER_TYPE_BUY_STOP | Lệnh dừng chờ mua | 4 |
ORDER_TYPE_SELL_STOP | Lệnh dừng chờ bán | 5 |
ORDER_TYPE_BUY_STOP_LIMIT | Khi đạt đến giá lệnh, lệnh chờ Buy Limit được đặt ở mức giá StopLimit | 6 |
ORDER_TYPE_SELL_STOP_LIMIT | Khi đạt đến giá lệnh, lệnh chờ Sell Limit được đặt ở mức giá StopLimit | 7 |
ORDER_TYPE_CLOSE_BY | Lệnh đóng vị thế bằng lệnh ngược lại | 8 |
Có một vài chục phép liệt kê khác nhau. Tên của chúng được thêm tiền tố "ENUM_". Chúng ta sẽ tìm hiểu chúng khi chúng ta di chuyển qua các miền có liên quan.
Mỗi phép liệt kê là một kiểu độc lập. Tuy nhiên, biểu diễn bên trong của chúng giống hệt nhau, tức là số nguyên bốn byte (int
). Mỗi hằng số liệt kê được mã hóa bằng một số hoặc kiểu khác, nhưng trong hầu hết các trường hợp, lập trình viên không cần phải nhớ những số này, vì toàn bộ mục đích của việc sử dụng phép liệt kê chính xác là thay thế các biểu diễn bên trong bằng các định danh rõ ràng.
Trình biên dịch đảm bảo rằng giá trị liệt kê luôn là một trong các hằng số được định nghĩa lại. Nếu không, cảnh báo hoặc lỗi biên dịch sẽ xảy ra (theo ngữ cảnh, hãy xem ví dụ).
Đây là cách liệt kê ENUM_DAY_OF_WEEK
xuất hiện "bên dưới" (script MQL5/Scripts/MQL5Book/p2/TypeEnum.mq5
).
void OnStart()
{
ENUM_DAY_OF_WEEK sun = SUNDAY; // sun = 0
ENUM_DAY_OF_WEEK mon = MONDAY; // mon = 1
ENUM_DAY_OF_WEEK tue = TUESDAY; // tue = 2
ENUM_DAY_OF_WEEK wed = WEDNESDAY; // wed = 3
ENUM_DAY_OF_WEEK thu = THURSDAY; // thu = 4
ENUM_DAY_OF_WEEK fri = FRIDAY; // fri = 5
ENUM_DAY_OF_WEEK sat = SATURDAY; // sat = 6
int i = 0;
ENUM_DAY_OF_WEEK x = i; // cảnh báo: chuyển đổi enum ngầm định
ENUM_DAY_OF_WEEK y = 1; // ok, bằng với MONDAY
ENUM_ORDER_TYPE buy = ORDER_TYPE_BUY; // buy = 0
ENUM_ORDER_TYPE sell = ORDER_TYPE_SELL; // sell = 1
// ...
// cảnh báo: chuyển đổi ngầm
// từ 'enum ENUM_DAY_OF_WEEK' sang ' ENUM_ORDER_TYPE'
// 'ENUM_ORDER_TYPE::ORDER_TYPE_SELL' sẽ được sử dụng
// thay vì 'ENUM_DAY_OF_WEEK::MONDAY'
ENUM_ORDER_TYPE type = MONDAY;
// lỗi biên dịch: bỏ chú thích để tái tạo
// ENUM_DAY_OF_WEEK day = ORDER_TYPE_CLOSE_BY; // không thể chuyển đổi enum
// ENUM_DAY_OF_WEEK z = 10; // '10' - không thể chuyển đổi enum
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Tất cả các hằng số của các ngày trong tuần đều được mã hóa bằng các số từ 0 đến 6, Chủ Nhật là điểm bắt đầu. Về cơ bản, các hằng số không nhất thiết phải có các số liên tiếp hoặc bắt đầu bằng 0. Có những phép liệt kê không phải như vậy.
Xin lưu ý rằng các hằng số giống nhau có thể có nghĩa khác nhau trong các kiểu liệt kê khác nhau. Ví dụ, đối với các lệnh ORDER_TYPE_BUY
và ORDER_TYPE_SELL
trong kiểu liệt kê ENUM_ORDER_TYPE
, các giá trị giống nhau (0 và 1) được sử dụng như đối với các ngày trong tuần là SUNDAY
và MONDAY
trong ENUM_DAY_OF_WEEK
.
Khi sao chép giá trị từ một biến số nguyên đơn giản i vào biến liệt kê x , trình biên dịch sẽ đưa ra cảnh báo vì có thể có một giá trị khác với các hằng số được phép trong biến i ở giai đoạn thực thi chương trình.
Trong biến y, chúng ta ghi số 1 có nghĩa là MONDAY và trình biên dịch coi đây là một phép toán đúng.
Một nỗ lực ghi hằng số của một phép liệt kê vào biến của phép liệt kê khác (như MONDAY cho kiểu biến trong ví dụ trên) có thể gây ra cảnh báo về chuyển đổi kiểu ngầm định. Điều này xảy ra nếu hằng số được ghi có cùng giá trị với một trong các phần tử của phép liệt kê mục tiêu. Nói cách khác, mỗi phép liệt kê trong hai phép liệt kê đều có phần tử riêng có giá trị liên quan. Sau đó, trình biên dịch tự động thực hiện chuyển đổi ngầm định thay cho lập trình viên, nhưng sử dụng cảnh báo để "yêu cầu" lập trình viên kiểm tra xem mọi thứ có diễn ra như mong muốn hay không: Thực tế là MONDAY sẽ được thay thế bằng ORDER_TYPE_SELL
quả thực là kỳ lạ; tuy nhiên, chúng ta đã cố ý làm như vậy ở đây vì mục đích minh họa.
Nếu phần tử được sao chép không khớp về giá trị với bất kỳ phần tử nào của phép liệt kê khác, thì lỗi biên dịch sẽ được tạo ra, vì không thể chuyển đổi ngầm định, chẳng hạn như khi viết ORDER_TYPE_CLOSE_BY
trong biến day.
Chuỗi được chú thích với biến z cũng gây ra lỗi biên dịch, vì giá trị 10 không thuộc về ENUM_DAY_OF_WEEK
. Nếu lập trình viên chắc chắn rằng, trong trường hợp ngoại lệ, vẫn cần ghi lại giá trị ngẫu nhiên trong biến kiểu liệt kê, họ có thể sử dụng ép kiểu rõ ràng.
Ép kiểu rõ ràng và ngầm định sẽ được thảo luận trong phần có tiêu đề Ép kiểu .
MQL5 cho phép lập trình viên khai báo các phép liệt kê được áp dụng của riêng họ bằng cách sử dụng từ khóa enum . Tính năng này được mô tả trong phần tiếp theo, Các phép liệt kê tùy chỉnh (enum
).