6

我只是想将我的代码从 C# 转换为 Haxe NME。我使用枚举作为标志。

[Flags]
enum State
{
    StateOne    = 1,
    StateTwo    = 2,
    StateThree  = 4
}

并使用它

if (someObj.HasState(State.StateOne | State.StateTwo))
{
    // Contains both the states. Do something now.
}

我不知道如何在 Haxe NME 中做到这一点。

谢谢。

4

2 回答 2

13

在 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;
    }
}
于 2013-05-17T04:25:46.110 回答
1

我设法找到了它。我在使用枚举时遇到了麻烦,但我成功地使用了常量。这是我使用的简单测试文件。

package ;

class FlagsTest
{

    static inline var FLG_1:Int = 1;
    static inline var FLG_2:Int = 2;

    public static function main() : Void
    {
        var flag:Int = FLG_1;
        if (hasFlag(flag, FLG_1))
        {
            trace ("Test 1 passed");
        }
        flag |= FLG_2;
        if (hasFlag(flag, FLG_2))
        {
            trace ("Test 2 passed");
        }
    }

    public static function hasFlag( flags:Int, flag:Int ) : Bool
    {
        return ((flags & flag) == flag) ? true : false;
    }

}

输出:

FlagsTest.hx line 14: Test 1 passed
FlagsTest.hx line 19: Test 2 passed
于 2013-05-16T13:37:10.027 回答