非类型类型参数

风湿病

如果我的类仅因代码中使用的某些常数而不同,该怎么办。是否有可能在没有运行时成本的情况下实现一个通用实现?

这是示例(有点长...)

@:enum abstract Param(Int) {
    var foo = 0;
    var bar = 1;
}

class WorkBase {

    public function new() {}

    private inline function work_impl(p: Param): Void {

        if(p == foo) {
            trace('foo');
        }
        else {
            trace('bar');
        }
    }

    public function work(): Void {

    }
}

class WorkFoo extends WorkBase{
    override public function work(): Void {
        work_impl(foo);
    }
}

class WorkBar extends WorkBase {
    override public function work(): Void {
        work_impl(bar);
    }
}

class Test {

    public static function main() {
        var workFoo = new WorkFoo();
        var workBar = new WorkBar();
        workFoo.work();
        workBar.work();
    }
}

经过编译之后,-D analyzer-optimize我们将看到WorkFoo.work()WorkBar.work()函数已经过优化,并且只包含一个与Param之一匹配的代码分支在现实生活中,中有很多这样的比较work_impl(),并且它们都已被优化。那很好。

但是,如果我不想要什么创造WorkFooWorkBar手工制作。是否可以做这样的事情:

@:generic
class WorkBase<PARAM> {
    private inline function work_impl(p: Param): Void {
        ...
    }

    public function work(): Void {
        work_impl(PARAM);
    }
}

我知道最接近的是const-type-parameter但是我觉得通用构建不是这里的好选择。

Gama11

我知道的最接近的东西是const-type-parameter。但是我觉得通用构建不是这里的好选择。

可以不使用@:genericBuildconst类型参数-将const类型参数与结合使用@:generic就足以实现所需的优化:

@:enum abstract Param(Int) from Int {
    var foo = 0;
    var bar = 1;
}

@:generic class Work<@:const PARAM:Int> {
    public function new() {}

    public function work():Void {
        if (PARAM == foo) {
            trace('foo');
        } else {
            trace('bar');
        }
    }
}

class Main {
    public static function main() {
        var workFoo = new Work<0>();
        var workBar = new Work<1>();
        workFoo.work();
        workBar.work();
    }
}

由于@:generic,会为每个常量值生成一个类,例如在JS上,输出如下所示:

var Work_$0 = function() {
};
Work_$0.prototype = {
    work: function() {
        console.log("source/Main.hx:11:","foo");
    }
};
var Work_$1 = function() {
};
Work_$1.prototype = {
    work: function() {
        console.log("source/Main.hx:13:","bar");
    }
};

请注意,由于某些原因,此示例在Haxe 3.4.7中由于“约束检查失败”而失败,但是在Haxe 4 Preview 4和更高版本中可以正常工作。另一个限制是既不工作new Work<Param.foo>()new Work<foo>()不起作用-您需要传递实际的常数值。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章