mixin 模拟多继承 博客分类: D语言 F#
程序员文章站
2024-03-19 17:25:40
...
D1.0 代码
- /** TupleMixin 演示程序, DMD2.007/GDC0.24 测试通过
- Written in the D programming language 1.0
- 作者: oldrev
- Copyrights: BSD
- */
- import std.stdio;
- //PredT 参数的作用是让你能够在每个模板混入之前对它进行处理,
- //比如可以在混入前用 static assert 检查是否有特定的成员
- //总而言之,PredT 给你机会控制混入时的细节。
- template MixinTuple(alias PredT, L...)
- {
- mixin PredT!(L[0]);
- static if(L.length > 1)
- mixin MixinTuple!(PredT, L[1..$]);
- }
- // P 是所有准备当做超类的模板
- class Mixinable(SuperClass, P...) : SuperClass
- {
- private const string InitCode = "private void initAllMixins() {";
- //PredT 的一个例子,混入且产生与模板同名的 alias
- template MixinWithAliasPred(alias X) {
- mixin("mixin X!() " ~ (X.stringof)[0..$-2] ~ ";"); //去掉模板名称后的 '()'
- }
- mixin MixinTuple!(MixinWithAliasPred, P);
- private template MakeInitCode(TL...)
- {
- static if(TL.length == 0)
- const string MakeInitCode = "";
- else
- { //"HasMember" 惯用法
- static if(is(typeof(mixin(TL[0].stringof[0..$-2] ~ "._ctor"))))
- { //如果TL[0] 有 _ctor 成员函数(也就是 this()),我们就产生调用 _ctor 的代码。
- const string MakeInitCode = TL[0].stringof[0..$-2] ~ "._ctor();\n" ~
- MakeInitCode!(TL[1..$]);
- }
- else //没有 _ctor,继续递归
- const string MakeInitCode = MakeInitCode!(TL[1..$]);
- }
- }
- protected this()
- {
- mixin(MakeInitCode!(P)); //产生并执行代码调用所有模板的 this()
- }
- }
- /////////////////////////////////////////////////////
- //开始演示:
- /////////////////////////////////////////////////////
- template Policy()
- {
- this() {
- writefln("Policy.this()");
- }
- ~this() {
- writefln("Policy.~this()");
- }
- void bar(T)(T x) {
- writefln("bar()");
- }
- }
- template Policy2()
- {
- this() {
- writefln("Policy2.this()");
- }
- ~this() {
- writefln("Policy2.~this()");
- }
- void foo() { writefln("Policy2.foo"); }
- }
- class SuperBar //超类,或者叫基类
- {
- this() {
- writefln("SuperBar.this()");
- }
- }
- // Mixinable 用法演示——模拟多继承
- // Foo 类是组合 Policy, Policy2 和 基类 SuperBar 的结果
- class Foo : Mixinable!(SuperBar, Policy, Policy2)
- {
- this() {
- writefln("Foo.this()");
- }
- void foo() { writefln("Foo.foo"); }
- ~this() {
- writefln("Foo.~this()");
- }
- }
- void main()
- {
- Foo f = new Foo;
- f.foo;
- f.bar(3);
- }
输出:
- SuperBar.this()
- SuperBar.this()
- Policy.this()
- SuperBar.this()
- Policy2.this()
- Foo.this()
- Foo.foo
- bar()
- Foo.~this()
- Policy2.~this()
- Policy.~this()
Have fun!