如果我的类仅因代码中使用的某些常数而不同,该怎么办。是否有可能在没有运行时成本的情况下实现一个通用实现?
这是示例(有点长...)
@: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()
,并且它们都已被优化。那很好。
但是,如果我不想要什么创造WorkFoo
和WorkBar
手工制作。是否可以做这样的事情:
@:generic
class WorkBase<PARAM> {
private inline function work_impl(p: Param): Void {
...
}
public function work(): Void {
work_impl(PARAM);
}
}
我知道最接近的是const-type-parameter。但是我觉得通用构建不是这里的好选择。
我知道的最接近的东西是const-type-parameter。但是我觉得通用构建不是这里的好选择。
可以不使用@:genericBuild
const类型参数-将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] 删除。
我来说两句