D cho phép định nghĩa các hàm mẫu tương tự như trong C++ hay Java, đó là các hàm tổng quát hay đối tượng của bất kỳ kiểu nào tương thích với các biểu thức của hàm:
auto add(T)(T lhs, T rhs) {
return lhs + rhs;
}
Tham số T
được chỉ ra trong cặp dấu ngoặc trước phần tham số hàm,
và trình biên dịch sẽ thay thế nó bởi kiểu thực sự nhờ toán tử !
như ví dụ sau:
add!int(5, 10);
add!float(5.0f, 10.0f);
add!Animal(dog, cat); // Animal không có phép +
// nên trình biên dịch báo lỗi ở đây
Các hàm mẫu chấp nhận hai kiểu tham số, một kiểu dùng cho lúc biên dịch,
và kiểu dùng dùng cho lúc chạy chương trình. (Với các hàm không phải là
hàm mẫu, chúng chỉ có các tham số lúc chạy run-time
.)
Các tham số cho lúc biên dịch không được chỉ ra tường minh, trình biên dịch
sẽ cố nội suy ra kiểu từ các tham số run-time
int a = 5; int b = 10;
add(a, b); // Tương đương với add!int(a,b)
float c = 5.0;
add(a, c); // T bây giờ là `float`
Một hàm có thể có nhiều tham số mẫu, ví dụ func!(T1, T2 ..)
.
Những tham số này thuộc về một trong các kiểu cơ bản, bao gồm kiểu chuỗi
và số thực chấm động.
Không như trong Java, mẫu của D chỉ sử dụng vào lúc biên dịch, và nó sẽ làm phát sinh các mã tối ưu cho các kiểu khác nhau lúc hàm thật sự được gọi.
Các kiểu struct
, class
, interface
cũng có thể dùng với mẫu:
struct S(T) {
// ...
}