Trong kiểu ghép hay lớp,
D cho phép bạn định nghĩa lại các toán tử
+
, -
, phép gọi hàm ()
. Liên quan đến khả năng này, ta sẽ bàn kỹ hơn
về hai hàm opDispatch
và opApply
.
Các kiểu ghép hay lớp có thể định nghĩa hàm thành phần opDispatch
để thay cho bất kỳ hàm thành phần nào chưa được định nghĩa tường minh.
opDispatch
nhận tên hàm thành phần chưa biết như là tham số mẫu, ở dạng chuỗi.
Ta còn nói opDispatch
là hàm catch-all; nó cho phép một mức khác
của việc lập trình tổng quát (generic programming
) tại lúc biên dịch mã nguồn.
struct C {
void callA(int i, int j) { ... }
void callB(string s) { ... }
}
struct CallLogger(C) {
C content;
void opDispatch(string name, T...)(T vals) {
writeln("called ", name);
mixin("content." ~ name)(vals);
}
}
CallLogger!C l;
l.callA(1, 2);
l.callB("ABC");
Thay vì định nghĩa kiểu dải (range) riêng để dùng với phép lặp foreach
,
ta có thể định nghĩa toán tử opApply
như là hành thành phần. Khi duyệt
với foreach
, hàm opApply
sẽ được gọi với tham số là một ủy nhiệm hàm đặc biệt:
class Tree {
Tree lhs;
Tree rhs;
int opApply(int delegate(Tree) dg) {
if (lhs && lhs.opApply(dg)) return 1;
if (dg(this)) return 1;
if (rhs && rhs.opApply(dg)) return 1;
return 0;
}
}
Tree tree = new Tree;
foreach(node; tree) {
...
}
Trình biên dịch chuyển hóa thân của foreach
thành một ủy nhiệm hàm đặc biệt,
trở thành đối tượng dùng như tham số của opApply
. Tham số duy nhất của
ủy nhiệm hàm chứa giá trị hiện tại của phép lặp. Kiểu trả về là int
,
và nếu nó không phải là 0
, phép lặp sẽ phải dừng lại.