如果我的类仅在代码中使用的某些常量不同,该怎么办?是否有可能在不花费运行时间的情况下实现一个通用实现?
这里是例子(有点长...)
@: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。但是我觉得通用构建不是一个不错的选择。
答案 0 :(得分:2)
我知道最接近的是const-type-parameter。但是我觉得通用构建不是一个不错的选择。
可以在不使用@:genericBuild
的情况下使用常量类型参数-与@: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>()
都不起作用-您需要传递实际的常数值。