对静态字段和类型推断的约束

时间:2017-03-29 14:04:20

标签: haxe

是否可以对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>
    }
}

但它失败了,因为type parameter constraints are checked lazily。关于如何做到的任何想法?

2 个答案:

答案 0 :(得分:2)

你考虑过使用typedef吗?

快速编辑代码,显示基本想法

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);
    }
}

示例try haxe!

您可以更改typedef中的实例类型以更适合您的需要,您也可以约束typedef,这可能非常有用

答案 1 :(得分:1)

如果您不介意使用宏,这里有一个可能的解决方案: 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);
    }
}

Macro.hx

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);
    }
}