我想使用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;
}
输出:
错误:函数AlsoWithFeature.FeaturesImplementer!()。feature1无法覆盖最终函数WithFeature.FeaturesImplementer!()。feature1
弃用:隐式覆盖基类方法WithFeature.FeaturesImplementer!()。feature2 with AlsoWithFeature.FeaturesImplementer!()。feature2 deprecated;添加'覆盖'属性
错误:mixin AlsoWithFeature.FeaturesImplementer!()错误实例化
我可以将typeStuff
放在另一个模板中,但问题是在FeaturesImplementer
中一切都在一起。功能甚至使用整数。有没有办法在内部使用相同的mixin?
答案 0 :(得分:1)
您可以使用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
的字段,但我不知道为什么编译器没有抱怨这个。