跳轉到內容

D 語言入門指南/模板和泛型程式設計/Mixins

來自 Wikibooks,開放的書籍,開放的世界

D 的類只支援單繼承和介面。雖然介面足以重現多重繼承的許多用途,但有些事情它們無法做到。Mixins 最初被新增到語言中是為了彌補這些不足。

普通模板

[編輯 | 編輯原始碼]

在討論 mixins 之前,有必要討論模板的正常語法。前兩章中討論的類和函式模板語法實際上是正規語法的簡寫形式。“正常”模板看起來像這樣

template Foo(A, B, C)
{
    A a;
    B b;
    C c;
}

模板由名稱(Foo)、引數列表(A、B、C)和一系列宣告(a、b、c)組成。當模板被例項化時,引數將被例項化提供的引數替換。宣告被放置在與模板相同的範圍內。

alias Foo!(int, real, char[]) F;
F.a = 10;
F.b = 5.8;
F.c = "hello!";

由於上面的例子不太有用,這裡介紹了上一節中“min”函式的長格式。

template min(T)
{
    T min(T t1, T t2)
    {
        if (t1 < t2) return t1;
        else return t2;
    }
}

這也展示了 D 模板的另一個有趣特性。如果模板包含一個宣告,並且該宣告與模板同名,那麼可以隱式地引用該成員。結合 _隱式函式模板例項化_(在上一節中討論過),以下都是等效的

min!(int).min(1, 2); // long form
min!(int)(1, 2); // with the single-element rule
min(1, 2); // with IFTI

通常,當模板被例項化時,它的宣告會被插入到模板所在的任何範圍內。在 mixin 中,宣告可以被插入到當前範圍內。一個簡單的例子如下所示

template Foo()
{
    int i;
    char[] s;
}
struct S
{
    mixin Foo;
}

(注意,如果模板的引數列表為空,那麼 mixin 可以省略!())。結果是結構 S 有兩個成員int ichar[] s.

Mixins 也可以命名,允許相同的 mixin 多次混合到當前範圍內。這是一個更復雜的例子。

template Writer(T)
{
    void write(T t)
    {
        writefln(t);
    }
}
struct S
{
    mixin Writer!(int) IntWriter;
    mixin Writer!(char[]) StrWriter;
}
S s;
s.IntWriter.write(12);
s.StrWriter.write("hello!");
華夏公益教科書