在 Haxe 3 中,有haxe.EnumFlags。这使用 Haxe 3抽象类型,它基本上包装了一个底层类型,在这种情况下,它使用一个 Int,就像你所做的一样 - 但是它把它包装在一个漂亮的 API 中,所以你不必担心细节。
这是一些示例代码:
import haxe.EnumFlags;
class EnumFlagTest
{
static function main()
{
var flags = new EnumFlags<State>();
flags.set(StateOne);
flags.set(StateTwo);
flags.set(StateThree);
flags.unset(StateTwo);
if (flags.has(StateOne)) trace ("State One active");
if (flags.has(StateTwo)) trace ("State Two active");
if (flags.has(StateThree)) trace ("State Three active");
if (flags.has(StateOne) && flags.has(StateTwo)) trace ("One and Two both active");
if (flags.has(StateOne) && flags.has(StateThree)) trace ("One and Three both active");
}
}
enum State
{
StateOne;
StateTwo;
StateThree;
}
所有这些工作都存储为标准 Int,并像您所做的那样使用整数运算符,因此它应该非常快(没有包装在外部对象中)。如果你想看看它在盒子下是如何工作的,可以在这里查看 EnumFlags 的源代码。
如果您仍在使用 Haxe 2,那么您可以创建一个非常相似的对象,但是当然,它必须创建一个对象以及整数,所以如果您要创建数千个(数百万个?)它们然后你可能会慢下来。应与 Haxe 2 一起使用的等效代码(尽管我尚未检查):
class MyEnumFlags<T:EnumValue>
{
var i:Int;
public function new(?i=0)
{
this.i = i;
}
public inline function has( v : T ) : Bool {
return i & (1 << Type.enumIndex(v)) != 0;
}
public inline function set( v : T ) : Void {
i |= 1 << Type.enumIndex(v);
}
public inline function unset( v : T ) : Void {
i &= 0xFFFFFFF - (1 << Type.enumIndex(v));
}
public inline static function ofInt<T:EnumValue>( i : Int ) : MyEnumFlags<T> {
return new MyEnumFlags<T>(i);
}
public inline function toInt() : Int {
return i;
}
}