[英]Casting to a Generic Type in Haxe
更新的问题:
我做了一些挖掘工作,并摆脱了劳伦斯·泰勒(Laurence Taylor)的回答。 我快到了,但似乎不适用于递归包装。 这是一个更新的可运行代码片段,显示了该问题(这次使用我的类,因为我不想重新定义所有内容)
具体来说,请注意, {t : 3}
(正确)第一次绑定到等价物,但是{t : {t : 3}}
(也正确)绑定到等价物,嵌套的{t : 3}
绑定到等价物nonequitable。 相同的对象t1
和t2
第一次绑定到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);}
}
本质上,我有一堆类(其中A
和B
只是两个),其中一些SelfReferringInterface
自己实现了SelfReferringInterface
(就像B
一样),而另一些则没有实现。
然后,我有了一个通用类,可以包装任何类型:
class GenericClass<T> {
private var t : T;
public function new(t : T) {this.t = t;}
}
我想向GenericClass<T>
添加一个方法,如果它是T
则SelfReferringInterface
的实现将调用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(..)
? 我可以控制所有类,但是我试图避免更改A
和B
来实现这一点。 我可以根据需要添加到SelfReferringInterface
或GenericClass
。 想法?
我进行了一些挖掘,由于协方差用法,我似乎希望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.