2017-05-06 19 views
1

あるタイプの配列を別の(抽象)タイプの配列として扱おうとしています。基礎となる型の抽象クラスを使用するとうまく動作します。しかし、別のタイプ(@:fromキーワードを使用して定義)を使用して暗黙の変換を試みると、ビルドに失敗します。Haxeの抄録 - @:fromを使用すると暗黙的に配列をキャストできますか?

私が明示的にcastを使用すると動作しますが、私は不思議です - これが何か不足していますか?以下の例では

、私はGama11とJustinfrontからの提案を取ると、ビルドに失敗Array<Int> should be Array<StringAbstract>

class Test { 
    static function main() { 
     var test:String = "Hello World"; 
     print(test); //this works 

     var testArr:Array<String> = ["Hello", "World"]; 
     printArray(testArr); //this works (using underlying type) 

     var testInt:Int = 10; 
     print(testInt); //this works 

     var testIntArr:Array<Int> = [1, 2, 3]; 
     printArray(cast testIntArr); //this works (explicit cast) 
     printArray(testIntArr); //build failure (using @:from) 
    } 

    static function print(s:StringAbstract) { 
     trace(s); 
    } 

    static function printArray(arr:Array<StringAbstract>) { 
     trace(arr); 
    } 
} 

abstract StringAbstract(String) from String to String { 
    inline function new(s:String) { 
     this = s; 
    } 

    @:from 
    static public function fromInt(i:Int) { 
     return new StringAbstract(Std.string(i)); 
    } 
} 

フォローアップ

を取得し、私はの配列に配列を変換するために、抽象的に定義されました私の抽象型。しかし、今私は別の問題に遭遇しています - @:を関数から宣言すると直ぐに動作していたコードが壊れます。

具体的には、暗黙的にアブストラクトに変換された「混合」タイプ(たとえばprintArray([1, "2", 3]);)の関数を呼び出すことができました。

しかし、別のタイプのアレイ(この場合はArray<Int>)から変換するために@:from関数を追加すると、エラーがArrays of mixed types are only allowed if the type is forced to Array<Dynamic>で破損します。

これがなぜ起こるのか誰かが分かっている場合は、好奇心が強いです(例:https://try.haxe.org/#65D03)。

class Test { 
    static function main() {   
     var testMixedArr:Array<StringAbstract> = [1, "2", 3]; 
     printArray(testMixedArr); //this works 
     printArray([1, "2", 3]); //this doesn't work, unless I remove "fromIntArray" function 
    } 

    static function printArray(arr:StringAbstractArray) {trace(arr);} 
} 


abstract StringAbstractArray(Array<StringAbstract>) from Array<StringAbstract> to Array<StringAbstract> { 
    inline function new(s:Array<StringAbstract>) { 
     this = s; 
    } 

    @:from 
    static public function fromIntArray(intArr:Array<Int>) { 
     return new StringAbstractArray(Lambda.array(Lambda.map(intArr, function(i: Int):StringAbstract { 
      return i; }))); 
    } 
} 

答えて

2

これを回避する唯一の方法はArray<Int>とる明示的な@:from関数を定義することです。この理由は、Variance section of the Haxe Manualで説明されています。この場合、どのようにしてキャストを実行すると、(コンパイラがキャッチするのではなく)実行時に安全でないコードを実行する可能性があるという良い例があります。

+0

は、感謝の意味があります。私は '@:from'関数をどこで定義しますか?別の要約を作成する必要がありますか? –

+0

このコードでは配列の@:を見ることができます。 https://github.com/nanjizal/triangulations/blob/master/triangulations/Vertices.hx#L125 – Justinfront

+0

これらの提案を実装しようとしました、そして、それは私のすべての既存の例のために働きました。しかし、もはや新しい抽象を追加した後に動作するようです別の例を思い付きました。誰かが見たいと思えば私の元の質問を更新しました。 –

1
printArray(Lambda.array(Lambda.map(testIntArr, function(v: Int):StringAbstract { 
      return v; }))); 

(新しいと間違いありません! - まだマックのナイトリーを更新するクリーナーが、基盤であるかもしれないので、再生することはできません>もの)

+0

はまた、あなたは、変換を支援するため、抽象配列を作成することができますが、おそらくあなたはまだループを必要とする、あなたが使用することができます:@すべての通常の配列のメソッドを取得するために転送します。 – Justinfront

0

は、これはトライhaXeの上で動作 をしているフォローアップあなたは確かにこれをやっている必要がありますか?ここ

class Test { 
    static function main() {   
     var testMixedArr:Array<StringAbstract> = [1, "2", 3]; 
     printArray(testMixedArr); //this works 
     printArray(new StringAbstractArray([1, "2", 3])); 
    } 

    static function printArray(arr:StringAbstractArray) { 
     trace(arr); 
    } 

} 


abstract StringAbstractArray(Array<StringAbstract>) from Array<StringAbstract> to Array<StringAbstract> { 
    inline public function new(s:Array<StringAbstract>) { 
     this = s; 
    } 

    @:from 
    static public function fromIntArray(intArr:Array<Int>) { 
    return new StringAbstractArray(Lambda.array(Lambda.map(intArr, function(i: Int):StringAbstract { 
     return i; }))); 
    } 
} 


abstract StringAbstract(String) from String to String { 
    inline function new(s:String) { 
     this = s; 
    } 

    @:from 
    static function fromInt(i:Int) { 
     return new StringAbstract(Std.string(i)); 
    } 
} 

http://try-haxe.mrcdk.com/#ED866

関連する問題