2017-03-29 15 views
1

Haxeの静的フィールドに対する制約はありますか?たとえば、対応するクラスの型の静的フィールドinstanceを持つクラスを持つことができます。また、パラメータとして渡されたクラスのインスタンスを返す関数が必要な場合があります。これは私の試みです:静的フィールドと型推論の制約

class Foo { 
    static public var instance = new Foo(); 
    function new() {} 
} 

class Test { 
    // get instance from every class that have static field instance 
    static function getInstance<T, ClassT:({instance:T}, Class<T>)>(t:ClassT):T { 
     return t.instance; 
    } 

    static function main() { 
     var a = getInstance(Foo); 
     $type(a); //Test.hx:14: characters 14-15 : Warning : Unknown<0> 
    } 
} 

が原因で失敗します。どのようにこれを行うには任意のアイデア?マクロを使用してもかまわない場合

答えて

1

、ここでは可能な解決策である:Macro.hx

http://try-haxe.mrcdk.com/#7d650

Foo.hx

class Foo { 
    static public var instance = new Foo(); 
    public var foo:Int; 
    function new() {} 
} 

class Test { 

    macro static function getInstance(e) return Macro.getInstance(e); 

    static function _getInstance<T, ClassT:({instance:T}, Class<T>)>(t:ClassT):T 
     return t.instance; 

    static function main() { 
     var a = getInstance(Foo); 
     $type(a); 
    } 
} 

import haxe.macro.Expr; 
import haxe.macro.Context.*; 
using tink.MacroApi; 

class Macro { 
    public static function getInstance(e:Expr) { 
     var ct = TPath(e.toString().asTypePath()); 
     return macro (Test._getInstance($e):$ct); 
    } 
} 
+0

が簡単にちょうどこのように行う、マクロを使用している場合ではない、非常に便利です、あまりにものtypedefを制約return macro $ e.instance; ' – romamik

+0

もちろん、すべてをマクロに移動しないようにします。必要に応じて、マクロコードに入れずに関数を拡張することができます。 – KevinResoL

+0

それは良い点だ – romamik

2

は、使用して検討していますtypedef?

HERESにあなたのコードの迅速な編集がtry haxe!

typedef HasInstance = { 
    var instance:Dynamic; 
} 

class Foo { 
    static public var instance = new Foo(); 
    function new() {} 
} 

class Bar { 
    static public var instance = new Bar(); 
    function new() {} 
} 

class Test { 
    // get instance from every class that have static field instance 
    static function getInstance<T:HasInstance>(t:T):T { 
     trace(t); 
     return t.instance; 
    } 

    static function main() { 
     var a = getInstance(Foo); 
     trace(a); 
     $type(a); 
     var b = getInstance(Bar); 
     trace(b); 
     $type(b); 
    } 
} 

例基本的な考え方を示すあなたのニーズに、より適切であるとのtypedef内インスタンスタイプを変更します、そしてあなたがすることもできます`マクロ静的関数のgetInstance (E:ExprOf >):ExprOf

+0

それはちょうど動作しません。あなたの例では 'a'は' Class '型ですが、' a'の実際の値は 'Foo'型です。これは実行時エラーで終了します。 – romamik

+1

これは最適な解決策ですが、Dynamicではなくgenericを使用できます。 http://try.haxe.org/#6cc96 – kobi7

+0

愚かな私、訂正のおかげで! – ediblebird