模闆可以生成 函數,結構,聯,類,接口和任何其他合法的D代碼 模闆插件
.
插入模闆執行個體,如下:
mixin a_template!(template_parameters)
//
mixin template EdgeArrayFeature(T, size_t count) {
//這裡定義`模闆插件`
T[count] edges;
void setEdge(size_t index, T edge) {
edges[index] = edge;
}
void printEdges() {
writeln("The edges:");
foreach (i, edge; edges) {
writef("%s:%s ", i, edge);
}
writeln();
}
}
然後将插件執行個體化至放插件的地方.
mixin EdgeArrayFeature!(int, 2);//這樣,在此插入.
//或這樣
struct Line {
mixin EdgeArrayFeature!(int, 2);
}
或這樣
struct Point {
int x;
int y;
}
void main() {
mixin EdgeArrayFeature!(Point, 5);
setEdge(3, Point(3, 3));
printEdges();
}
模闆插件必須用
本地導入
,避免在導入點,找不到子產品.
module a;
mixin template A(T) {
//A,放在此處也可以,在插件的域中.
string a() {
import std.string;//必須放在内部
//否則,放在外部,模闆插件執行個體化後,可能編譯不過
T[] array;
// ...
return format("%(%s, %)", array);
}
}
找到自己的類型
this
mixin template MyMixin(T) {
void foo(this MixingType)() {//自己類型
import std.stdio;
writefln("插件所在的實際類型: %s",MixingType.stringof);
}
}
struct MyStruct {
mixin MyMixin!(int);
}
void main() {
auto a = MyStruct();
a.foo();
}
除了
插件模闆
,還有
插件串
,D又一個非常強大的特征.
mixin(compile_time_generated_string)
import std.stdio;
void main() {
mixin (`writeln("hello world");`);
}
厲害在于,代碼是編譯時生成.
import std.stdio;
string printStatement(string message) {
return `writeln("` ~ message ~ `");`;
}
void main() {
mixin (printStatement("hello world"));
mixin (printStatement("hi world"));
}
插件名字歧義:
import std.stdio;
template Templ() {
int i;
void print() {
writeln(i); //模闆中的i
}
}
void main() {
int i;
mixin Templ;
i = 42; // 主中的i
writeln(i); // 主中
print(); // 模闆中
}
多插件名沖突,解決:
mixin Templ A; // Defines A.i
mixin Templ B; // Defines B.i
//再定義一個名字.
A.i = 42;
串插件沒有名字空間.
void main() {
mixin ("int i;");
mixin ("int i;"); // 編譯錯誤
i = 42;
}
一種簡單消歧方法,把
串插件
搞成
模闆插件
,然後消歧:
template Templatize(string str) {
mixin (str);
}
void main() {
mixin Templatize!("int i;") A;//靠的是這兩句
mixin Templatize!("int i;") B;//靠的是這兩句
A.i = 42;//消歧
}
串插件
在操作符重載時,很有用.操作符重載定義為模闆也是為了友善生成代碼.
串插件
用在析構器中:
import std.stdio;
mixin template Foo() {
~this() {
writeln("Destructor mixed-in by Foo");
}
}
mixin template Bar() {
~this() {
writeln("Destructor mixed-in by Bar");
}
}
struct S {
~this() {
writeln("Actual destructor");
}
mixin Foo;
mixin Bar;
}
void main() {
auto s = S();
}
int[] filter(string predicate)(in int[] numbers) {
int[] result;
foreach (number; numbers) {
if (mixin (predicate)) {
result ~= number;
}
}
return result;
}
int[] numbers = [ 1, 8, 6, -2, 10 ];
int[] chosen = filter!"number < 7"(numbers);