Haxe泛型函数中的不同代码路径

时间:2016-07-12 17:29:57

标签: flash haxe

假设我想在Haxe中创建一个带有闪存ByteArrayArray的通用内联函数。

@:generic public static inline function WriteArray<T:(UInt, Int, Float)>(ba:ByteArray, array:Array<T>):Void
{
    if (array == null)
    {
        ba.writeInt(-1);
    }
    else
    {
        ba.writeInt(array.length);
        for (i in 0...array.length)
        {
            // here is where I have a problem
            // ba.writeUnsignedInt(array[i]); if T is UInt
            // ba.writeDouble(array[i]); if T is Float
            // ba.writeInt(array[i]); if T is Int
        }
    }
}

所以,我需要一些方法让每个生成的函数在那里使用不同的行。此代码需要具有高性能,因此不能选择对类型进行运行时检查。我也无法传递哪个写入函数用作参数(writeFunc:T->Void)b / c我们当前正在编译为Flash,而Flash每次引用时都会创建一个MethodClosure对象函数,垃圾收集器不能很好地处理它们(无论函数是否内联,都会发生这种情况)。我也试过使用宏,但你不能在宏内部的flash库中使用任何东西(我有类似的函数用于编写flash向量,我们仍然使用flash的ByteArray实现)。我希望有一种方法可以在编译时获得T,但我发现的只有${type}而且我认为你不能有条件地使用它。

那么,有没有办法让这个函数在ByteArray上调用正确的write方法而不创建对该函数的引用?它不一定要使用@:generic,但我认为约束会有所帮助。其他实施想法也将受到欢迎。现在我只有3个相同功能的版本,而c / p代码只是让我呕吐在我的嘴里。

1 个答案:

答案 0 :(得分:4)

  

我也试过使用宏,但你不能在宏内的flash库中使用任何东西

这并非完全正确:您实际上无法在宏中使用 Flash API,但您可以生成使用它的代码。您只需确保不将其添加为文件顶部的import - 语句,而是使用完全限定名称(flash.utils.ByteArray)。

这是一个简单的例子:

import haxe.macro.Context;
import haxe.macro.Expr.Access;
import haxe.macro.Expr.FieldType;

class Macro {
    public static function build() {
        var fields = Context.getBuildFields();
        fields.push({
            name:  "byteArray",
            access:  [Access.APublic, Access.AStatic],
            kind: FieldType.FVar(macro:flash.utils.ByteArray, null), 
            pos: Context.currentPos(),
        });
        return fields;
    }
}

...生成:

public static var byteArray:flash.utils.ByteArray;