Các phép liệt kê tùy chỉnh
Các phép liệt kê tùy chỉnh về mặt cấu trúc dựa trên kiểu int và các nguyên tắc sử dụng chúng hoàn toàn trùng khớp với những gì đã thảo luận ở trên trong phần trước về các phép liệt kê nhúng. Do đó, chúng ta đang mô tả các phép liệt kê tùy chỉnh ở đây, mặc dù, nói một cách nghiêm ngặt, chúng không được nhúng.
Để mô tả phép liệt kê của riêng bạn trong mã MQL5, bạn sẽ sử dụng từ khóa enum
. Dạng mô tả đơn giản nhất như sau:
enum name
{
element1,
element2,
element3
};
2
3
4
5
6
Mô tả này đăng ký trong chương trình một kiểu liệt kê có tên là name
với các phần tử được phân cách bằng dấu phẩy được bao quanh bởi dấu ngoặc nhọn (số lượng của chúng chỉ bị giới hạn bởi giá trị int
cao nhất, có thể được coi là không có giới hạn nào về mặt nhiệm vụ thực tế). Các định danh element1
, element2
và element3
sau đó có thể được sử dụng trong chương trình trong ngữ cảnh mà chúng đã được định nghĩa: Toàn cục (tức là bên ngoài tất cả các hàm) hoặc bên trong một hàm (xem phần Ngữ cảnh, khả năng hiển thị và thời gian tồn tại của các biến).
WARNING
Vui lòng xem xét dấu chấm phẩy theo sau dấu ngoặc nhọn đóng. Nó là cần thiết vì mô tả liệt kê là một câu lệnh riêng biệt và dấu chấm phẩy phải được đặt sau bất kỳ câu lệnh MQL5 nào.
Theo mặc định, các định danh có giá trị hằng số, bắt đầu bằng 0, mỗi định danh tiếp theo lớn hơn định danh trước đó 1. Nếu cần, lập trình viên có thể định nghĩa một giá trị cụ thể cho mỗi phần tử, sau =
bên phải định danh. Ví dụ, mục nhập ở trên tương đương với mục nhập này:
enum name
{
element1 = 0,
element2 = 1,
element3 = 2
};
2
3
4
5
6
Được phép chỉ định các hằng số hoặc biểu thức chỉ có giá trị mà trình biên dịch có thể tính toán ở giai đoạn biên dịch (để biết thêm chi tiết, vui lòng xem ví dụ bên dưới).
Nếu các giá trị không được xác định cho tất cả các phần tử, các giá trị bị bỏ qua sẽ được tính toán tự động dựa trên các giá trị đã biết gần nhất (trước đó) bằng cách thêm 1. Ví dụ:
enum name
{
element1 = 1,
element2,
element3 = 10,
element4,
element5
};
2
3
4
5
6
7
8
Tại đây, hai phần tử đầu tiên có giá trị là 1 và 2 (được tính toán), trong khi các phần tử bắt đầu bằng phần tử thứ ba có giá trị là 10 (được chỉ định rõ ràng), 11 và 12 (hai phần tử cuối cùng được tính toán dựa trên 10).
Trong tập lệnh TypeUserEnum.mq5
, có một số ví dụ về cách mô tả các liệt kê tùy chỉnh.
const int zero = 0; // giá trị thời gian chạy không được biết đến tại thời điểm biên dịch
enum
{
MILLION = 1000000
};
enum RISK
{
// OFF = zero, // error: constant expression required
LOW = -1,
MODERATE = -2,
HIGH = -3,
};
enum INCOME
{
LOW = 1,
MODERATE = 2,
HIGH = 3,
ENORMOUS = MILLION,
};
void OnStart()
{
enum INTERNAL
{
ON,
OFF,
};
// int x = LOW; // truy cập mơ hồ, có thể là một trong hai giá trị của RISK hoặc INCOME
int x = RISK::LOW;
int y = INCOME::LOW;
}
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
27
28
29
30
31
32
33
34
35
- Enumeration
INTERNAL
cho thấy khả năng mô tả nó bên trong hàm và khi làm như vậy, sẽ giới hạn vùng hiển thị/khả dụng của kiểu này, điều này rất hữu ích khi nói đến xung đột tên. - Enumeration
RISK
cho thấy các phần tử có thể được gán giá trị âm. Phần tử được chú thích OFF không thể được mô tả do nỗ lực khởi tạo nó bằng một biểu thức không phải hằng số: Trong trường hợp này, biến số không được chỉ định ở đó, giá trị của biến số không thể được trình biên dịch tính toán. - Trong phép liệt kê INCOME, phần tử ENORMOUS được khởi tạo thành công bằng giá trị từ phần tử MILLION của phép liệt kê khác được định nghĩa ở trên. Các phép liệt kê được tạo tại thời điểm biên dịch và do đó, chúng có sẵn trong các biểu thức khởi tạo.
- Enumeration với
MILLION
không có tên, các enumeration như vậy được gọi là anonymous. Ứng dụng cơ bản của chúng là khai báo hằng số. Tuy nhiên, enumeration có tên được sử dụng thường xuyên hơn cho các hằng số, vì chúng cho phép nhóm các phần tử theo ý nghĩa của chúng.
Vì có 2 phép liệt kê được định nghĩa trong ví dụ, cả hai đều có các phần tử có tên giống hệt nhau, việc chỉ định định danh LOW khi khai báo biến x dẫn đến lỗi biên dịch "truy cập mơ hồ", vì không rõ phần tử nào được liệt kê. Xin lưu ý rằng các định danh có thể có (và trong trường hợp này là như vậy) các giá trị khác nhau.
Để giải quyết vấn đề này, có một toán tử ngữ cảnh đặc biệt: Hai dấu hai chấm, ::
. Chúng giúp tạo thành định danh đầy đủ của phần tử ngôn ngữ, tức là phần tử liệt kê, trong trường hợp của chúng ta: Đầu tiên, tên liệt kê được chỉ định, sau đó là toán tử ::
, và sau đó là định danh phần tử. Ví dụ: RISK::LOW
và INCOME::LOW
. Chúng ta sẽ tìm hiểu về tất cả các toán tử trong phần có liên quan.