天天看點

48用d程式設計插件

模闆可以生成

函數,結構,聯,類,接口和任何其他合法的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);
           

繼續閱讀