簡體   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