我想使用mixin来实现一个接口.这工作正常,直到我继承.问题是mixin模板还实现了模板功能.
就像是:
interface Features {
void feature1();
void feature2();
}
mixin template FeaturesImplementer() {
int bar;
final void feature1(){}
void feature2(){}
void typeStuff(T)(){}
}
class WithFeature: Features {
mixin FeaturesImplementer;
this(){typeStuff!(typeof(this));}
}
class AlsoWithFeature: WithFeature {
mixin FeaturesImplementer;
this(){typeStuff!(typeof(this));}
}
void main() {
new WithFeature;
new AlsoWithFeature;
}
输出:
Error: function AlsoWithFeature.FeaturesImplementer!().feature1 cannot override final function WithFeature.FeaturesImplementer!().feature1
Deprecation: implicitly overriding base class method WithFeature.FeaturesImplementer!().feature2 with AlsoWithFeature.FeaturesImplementer!().feature2 deprecated; add ‘override’ attribute
Error: mixin AlsoWithFeature.FeaturesImplementer!() error instantiating
我可以把typeStuff放在另一个模板中,但问题是在FeaturesImplementer中,一切都在一起.功能甚至使用整数.有没有办法在内部使用相同的mixin和everuthing?
最佳答案 您可以使用
static if
表达式进行一些静态检查,该表达式在编译时进行评估.我们的想法是使用特征来验证实现是否已经在这里,特别是
hasMember
.
如果第一次混合模板,您还必须使用std.traits进行检查,在您的示例中,它等同于检查祖先(对象)是否已经是要素.
例如:
interface Features {
void feature1();
void feature2();
}
mixin template FeaturesImplementer() {
import std.traits: BaseClassesTuple;
alias C = typeof(this);
enum OlderHave = is(BaseClassesTuple!C[0] : Features);
enum Have = is(C : Features);
enum Base = Have & (!OlderHave);
static if (Base || !__traits(hasMember, C, "bar"))
int bar;
static if (Base || !__traits(hasMember, C, "feature1"))
final void feature1(){}
static if (Base || !__traits(hasMember, C, "feature2"))
void feature2(){}
void typeStuff(T)(){}
}
class WithFeature: Features {
mixin FeaturesImplementer;
this(){typeStuff!(typeof(this));}
}
class AlsoWithFeature: WithFeature {
mixin FeaturesImplementer;
this(){typeStuff!(typeof(this));}
}
void main() {
new WithFeature;
new AlsoWithFeature;
}
然后,如果不存在,则仅混合不同的功能实现.
请注意,由于int字段被重新声明,原始代码中也存在隐藏的问题,具体取决于您实例化的方式,字段可能是WithFeature或AlsoWithFeature,但我不知道编译器为什么会这样做不要抱怨.