使用 mixin 时关于覆盖方法的警告

Warning about overriden methods when using a mixin

我想使用 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?

您可以使用 static if expression, which evaluates at compile time. The idea is to verify if the implementation is already here, using the traits, particularly 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 或 [=14 之一=], 但我不知道为什么编译器没有抱怨。