繁体   English   中英

在Haxe中强制转换为通用类型

[英]Casting to a Generic Type in Haxe

更新的问题:

我做了一些挖掘工作,并摆脱了劳伦斯·泰勒(Laurence Taylor)的回答。 我快到了,但似乎不适用于递归包装。 这是一个更新的可运行代码片段,显示了该问题(这次使用我的类,因为我不想重新定义所有内容)

新的可运行代码示例

具体来说,请注意, {t : 3} (正确)第一次绑定到等价物,但是{t : {t : 3}} (也正确)绑定到等价物,嵌套的{t : 3}绑定到等价物nonequitable。 相同的对象t1t2第一次绑定到Equitable ,而第二次绑定到NonEquitable如何?


问题v1:

我正在通过Haxe进行挑战,并达到了简化这一点的目的:

interface SelfReferringInterface<X> {
    public function doStuff(x : X) : Void;
}

class A {
    private var x : Int;
    public function new(x : Int){this.x = x;}

    public function toString() {return Std.string(x);}
}

class B implements SelfReferringInterface<B> {
    private var x : Int;

    public function new (x : Int){this.x = x;}

    public function doStuff(b : B) {
        trace(this + " and " + b);
    }

    public function toString() { return Std.string(x);}
}

本质上,我有一堆类(其中AB只是两个),其中一些SelfReferringInterface自己实现了SelfReferringInterface (就像B一样),而另一些则没有实现。

然后,我有了一个通用类,可以包装任何类型:

class GenericClass<T> {
    private var t : T;
    public function new(t : T) {this.t = t;}
}

我想向GenericClass<T>添加一个方法,如果它是TSelfReferringInterface的实现将调用doStuff,否则具有一些其他默认行为:

class GenericClass<T> {
    private var t : T;
    public function new(t : T) {this.t = t;}

    public function doStuffOrTrace(t2 : T) {
         //if t instanceof SelfReferringClass, call t.doStuff(t2)
         //otherwise call trace(t) and ignore t2
    }
}

这样,以下测试方法即可完成以下任务。

class Test {
    static function main() {
        new GenericClass<A>(new A(3)).doStuffOrTrace(new A(4));//Expect 3
        new GenericClass<B>(new B(1)).doStuffOrTrace(new B(2));//Expect 1 and 2
    }
}

是否有可能实现doStuffOrTrace(..) 我可以控制所有类,但是我试图避免更改AB来实现这一点。 我可以根据需要添加到SelfReferringInterfaceGenericClass 想法?


我进行了一些挖掘,由于协方差用法,我似乎希望SelfReferringInterface<X>typedef而不是interface 我仍然对实现doStuffOrTrace(..) ,但这也许会开辟新的途径?

最好编写一个包含两种情况的枚举,将其包装为一个摘要,然后为每种情况编写@:from函数,并将其用作doStuffOrTrace的输入。

在正常使用中,调用该函数将导致调用正确的抽象构造函数,然后可以在内部使用开关进行区分。

*编辑

@:from static public function fromHasInterface<T>(v:SelfReferringInterface<T>):HasInterfaceOrNot<T>{
  return THasInterface(v);
}
enum HasInterfaceOrNotT<T>{
  THasInterface(v:SelfReferringInterface<T>);
  THasNotInterface(v:Dynamic);
}

在这里查看运行代码

您可以使用Std.is实现doStuffOrTrace来确定t的类型并将其转换为SelfReferringInterface:

public function doStuffOrTrace(t2 : T) {
    if(Std.is(t, SelfReferringInterface)){
        var castedT = cast(t, SelfReferringInterface<Dynamic>);
        castedT.doStuff(t2);
    }else{
        trace(t);
    }
}

问题是您永远不会明确使用toString方法,因此编译器(dce)会将其剥离,并且trace(t)将输出'[object]'

您可以通过在方法中添加@:keep元数据来防止这种情况,但是由于无法修改A和B,因此可以使用-dce no-dce std编译器标志禁用dce。

这是try.haxe片段: http ://try.haxe.org/#40402

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM