铸造一个泛型类型中HAXE
修订问题:铸造一个泛型类型中HAXE
我已经做了一些挖掘和工作过劳伦斯·泰勒的回答。我几乎在那里,但它似乎不能与递归包装。这里有一个更新的可运行的代码片段,它显示了问题(这次使用我的类,因为我不想重新定义一切)
具体地,请注意,{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
(如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
。想法?
我已经做了一些挖掘,它似乎(由于协方差useages),我宁愿SelfReferringInterface<X>
是的typedef而非接口。我仍然坚持实施doStuffOrTrace(..)
,但也许这会打开新的途径?
最佳写具有这两种情况下的枚举,包裹在一个抽象的及写入@:从功能每种情况下,和使用,作为输入到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);
}
看到正在运行的代码here
你可以使用Std.is确定T的类型和其转换成SelfReferringInterface实施doStuffOrTrace:
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]'
您可以防止通过添加@:保留元数据的方法,但由于 不能修改A和B,你可以用-dce no
或-dce std
编译器标志
这里禁用DCE是try.haxe片段: http://try.haxe.org/#40402
我想尝试的一件事是明确输入包装的输出,对泛型类型的类型解析有一些含糊之处。 因为应该隐式调用抽象构造函数,所以你不应该首先明确地调用wrap,并且可以完全避免Equatable的问题。 –