2016-07-12 6 views
3

HaxeでフラッシュByteArrayArrayのジェネリックインライン関数を作成したいとしましょう。Haxeジェネリック関数内の異なるコードパス

@: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 
     } 
    } 
} 

したがって、生成された関数のそれぞれに異なる行を使用するには、何らかの方法が必要です。このコードは実行可能である必要があるため、タイプのランタイムチェックはオプションではありません。また、現在Flashにコンパイルしているパラメータ(writeFunc:T->Void)b/cとして使用する書き込み関数を渡すことはできません.Flashは関数への参照を行うたびにMethodClosureオブジェクトを作成し、ガベージコレクタは、それらをうまく扱うことはできません(これは関数がインラインであるかどうかにかかわらず発生します)。また、マクロを使用しようとしましたが、マクロ内でフラッシュライブラリのものを使用することはできません(私はフラッシュベクトルを書き込むための同様の機能を持っていますが、まだフラッシュのByteArray実装を使用しています)。コンパイル時にTを取得する方法があると願っていますが、私が見つけたのは${type}で、条件付きで使うことはできません。

したがって、その関数への参照を作成せずにByteArrayで正しい書き込みメソッドを呼び出す方法がありますか?それは必ずしも@:genericを使用する必要はありませんが、私は制約が役に立つと考えています。他の実装の考え方も歓迎されるだろう。今、私はちょうど同じ機能の3つのバージョンを持っているし、私の口の中に投げることができます。

答えて

4

私はまた、マクロを使用しようとしたが、あなたは完全に真実ではないマクロ

内部のフラッシュライブラリーから何かを使用することはできません:あなたは、実際にフラッシュAPIを使用することはできませんマクロでは、それを使用するコードを生成することができます。ファイルの先頭にimport-statementとして追加しないでください。完全修飾名(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; 
関連する問題