[英]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.