2012-04-25 11 views
0

Vectorの型としてObjectまたは*を使用すると、汎用の機能(JavaのListなど)は提供されません。目撃者:汎用リストユーティリティでベクトル(AS3)を使用できますか?

public static function someGenericVectorUtil (value:Vector.<*>) :void { 
    // do stuff to/with the Vector 
} 

var someVector:Vector.<Number>; 
someGenericVectorUtil(someVector); // compile-time implicit coercion error 

おそらく、私たちはユーティリティメソッドを再定義して、配列を受け入れることにします。しかし、ベクターは、配列へのユーティリティに入るに変換する簡単な方法は、また戻って、その後でそれらをパックする簡単な方法は、このようなコードで、その結果、ありません:回答

public static function someGenericArrayUtil (value:Array) :void { 
    // do stuff to/with the formerly-known-as-Vector 
} 

var someVector:Vector.<Number>; 
var tempArray:Array = new Array(someVector.length); 
for (var i:uint=0; i<someVector.length; i++) { 
    tempArray[i] = someVector[i]; 
} 
someGenericVectorUtil(tempArray); 
someVector = Vector.<Number>([tempArray]); 

言うまでもないが、それはかなり恐ろしいです。さて、Vector-Array-Vectorナンセンスをユーティリティに移してみましょう:

public static function vectorToArray (Vector.<*>) :Array { 
    // oh wait....that Vector.<*> param is useless, 
    // as demonstrated earlier. 
} 

この混乱をまっすぐにする方法はありますか?あるいは、汎用ユーティリティで実行する必要があると思ったら、ベクターの使用をやめるべきですか? (明らかに、多くのオプションもありません...)

+0

注:ベクトルは、数値型(数値、整数、単位)を扱うときに効果があります。それ以外の場合は実際には遅いです。 – Marty

+0

ほとんどの場合、それほど遅いわけではありませんが、コードの可読性には間違いなく優れたインターフェースを提供します。また、今後のバージョンのフラッシュでは、型指定されたコンテナにこのような最適化を書き込むことができるため、他の型のVectorsを高速化する可能性があります。 –

答えて

3
public static function someGenericVectorUtil (value:Vector.<*>) :void { 
    // do stuff to/with the Vector 
} 

var someVector:Vector.<Number>; 
someGenericVectorUtil(Vector.<*>(someVector)); 

^それが動作します。また、配列で試してください。

+0

+1 "try with array"です。ベクトルを使用し、その型を "any" aka "*"として指定するのは役に立たない。ベクトルへの全体的なポイントは、厳密にコンテナをタイプすることができるため、メンバーにアクセスするときにRTTIが発生することはありません。メンバーはすべて1つのタイプである必要があるからです。ベクトルを使うことで0の利益を得ているので、Arrayを使うこともできます。 –

+0

ああVectorにキャストします。 <*>。とった。ありがとう! – ericsoco

+0

@AscensionSystems、もちろん、私はベクトルを*とタイプする点を理解しています。私の例の場合、Numberは*のサブクラスではないという事実を見逃してしまったので、多態性はここでは機能しません。 – ericsoco

0

これは答えではありませんが、@ Lukaszの答えにもっと長いコメントがあります。

彼の答えの問題は、実際に新しいベクターを作成していることです。そのため、ベクターをsomeGenericVectorUtilから戻して、再キャストする必要があります。例えば。試してみてください。

var v:Vector.<int> = Vector.<int>([1,2,3]); 
trace(v == Vector.<int>(Vector.<*>(v))); // traces false 

コードがちょうどintsの簡単なベクトルを作成すること、そして(当時intに、最初*に)キャスト自体のバージョンと比較します。ベクタをトレースすると、それらは同じになりますが、実際のベクタ参照自体は同じオブジェクトではありません。したがって、ベクターを変更するユーティリティ関数(シャッフルまたはランダム化関数など)を使用している場合は、何も変わりません。

例:

var v:Vector.<int> = Vector.<int>([1,2,3]); 
trace(v); // traces "1,2,3" 

// shuffle() randomises the elements in a vector - this first call won't work 
// as the cast creates a new vector 
VectorUtil.shuffle(Vector.<*>(v)); 
trace(v); // traces "1,2,3" 

// we need to recast it back, and change shuffle() to return the vector 
v = Vector.<int>(VectorUtil.shuffle(Vector.<*>(v))); 
trace(v); // traces "3,1,2" 

あなたが見ることができるように、それは終わりに向かって少し醜い取得を開始し、あなたがどこか他のベクトルを追跡している場合、あなたが参照を更新する必要がありますこれまでに見つかった唯一の解決策です:S

関連する問題