サイトトップ

Director Flash 書籍 業務内容 プロフィール

Adobe Flash非公式テクニカルノート

Vectorクラス

ID: FN0902001 Platform: All Version: CS5/ActionScript 3.0 Runtime: Flash Player 10/AIR 1.5

Vectorクラス
パッケージ トップレベル
クラス public dynamic class Vector
継承 Vector → Object

説明
Vectorインスタンスは、予め定めたひとつのデータ型の複数の値をエレメントとしてもつことができます。エレメントのデータ型が厳密に指定されることにより、その処理が最適化されたいわば厳格な配列と考えられます[*1]

VectorとArrayクラス
まず、Vectorクラスのインスタンスには、配列(Arrayクラス)と同じく、複数の値がエレメントとして納められます。つぎに、VectorクラスのプロパティやメソッドはArrayとほとんどが同じで、lengthプロパティやpush()pop()slice()sort()といったメソッドを備えています。

    【配列と似ている点】
  • 複数のエレメントを操作できる。
  • プロパティやメソッドはArrayクラスとほとんど同じ。

しかし、Vectorインスタンスはおもにふたつの点で、配列(Arrayインスタンス)とは扱いが異なります。第1に、すべてのエレメントがひとつのデータ型で指定されます。したがって、他の型のデータをエレメントにすることはできません。第2に、エレメントのインデックスは連番、つまり密(dence)でなければなりません。Vector.lengthプロパティの値より大きいインデックスには、エレメントが加えられません。

    【配列と異なる点】
  • すべてのエレメントにひとつのデータ型が指定される。
  • エレメントのインデックスは密(連番)でなければならない。

Vectorクラスはエレメントにひとつのデータ型が指定され、エレメントは密であることにより、大きくふたつの利点があります[*2]

    【Vectorクラスの利点】
  • パフォーマンスが高い。
  • データ型のチェックが厳格。

第1は、パフォーマンスの高さです。Vectorインスタンスのエレメントへのアクセスは、配列よりもずっと高速です(なお、後述注[*6]参照)。第2は、データ型のチェックが厳格なことです。[Strictモード][*3]では、コンパイラがデータ型の適合性を調べます[*4]。Vectorエレメントにデータ型の合わない値を設定したり、取出したエレメントを異なる型のデータとして扱わないか確認します。

[*1] Vectorというクラス名は、複数の値をひと組で扱うという数学的なベクトルの概念からつけられたものと想像されます。3次元空間の座標や空間ベクトルを処理するVector3Dクラスとは関係がありませんので、ご注意ください。

[*2] Vectorクラスの特長や配列と比べた利点については、Adobeデベロッパーセンター「ActionScript 3.0におけるパフォーマンス向上のヒント」の05「ArrayとVectorクラス」をご参照ください。また、F-site「Vectorクラス対Arrayクラスの処理速度比較」ではサンプルスクリプトで速さを比べています。

[*3] [Strictモード]は、コンパイラ警告を報告するデフォルトの設定です。[ファイル]メニューの[パブリッシュ設定]で[Flash]タブからActionScript 3.0の[設定]ボタンをクリックし、[ActionScript 3.0の詳細設定]ダイアログボックスで選択できます(図001)。

図001■[ActionScript 3.0の詳細設定]ダイアログボックスで[Strictモード]を設定

[*4] ただし、Vector.push()Vector.unshift()メソッドによりVectorにエレメントを加えると、後述(「Vectorエレメントの操作」)のとおり引数値のデータ型はコンパイル時には確認されず、ランタイム(実行時)にチェックされます。

Vectorクラスのコンストラクタメソッドとデータ型指定
Vectorクラスのコンストラクタメソッドは、以下のようなシンタックスでインスタンスを生成します。山括弧<>内に記述するベース型は、エレメントのデータ型を指定します。なお、山括弧<>でベース型を指定する記述は、「型パラメータシンタックス」と呼ばれます。

【Vectorコンストラクタ】
Vector.<ベース型>(長さ:uint=0, 長さの固定:Boolean=false)

コンストラクタの呼出しには、必ずベース型を記述しなければなりません。ベース型を指定しないと、ランタイムエラーが生じます。ベース型には、変数宣言や関数定義のデータ型と同じく、どのようなクラスでも指定することができます。

第1引数の[長さ]として正の整数を渡すと、生成されるVectorインスタンスのエレメント数(長さ)がその値に設定されます。デフォルト値は0です。長さを定めると、各エレメントの値はベース型のデフォルト値として扱われます[*5]。第2引数の[長さの固定]にtrueを指定すると、Vectorインスタンスのエレメント数(長さ)は後から変えることができません[*6]。デフォルト値は、変更を可能とするfalseです。

変数の宣言や関数の定義でデータ型としてVectorクラスを指定するときは、型パラメータシンタックスでベース型を指定する必要があります。たとえば、エレメントを整数とするVectorインスタンス(長さ0)を生成して、変数myVectorに代入するステートメントはつぎのようになります。

var myVector:Vector.<int> = new Vector.<int>();

Vector型データの代入式の両辺は、ベース型まで厳密に一致しなければなりません。つまり、ベース型が整数(int)のVectorインスタンスは、数値(Number)型Vectorの変数には代入できません。また、ベース型をSpriteで指定したVectorインスタンスは、スーパークラスであってもDisplayObjectをベース型とするVectorの変数に設定することもできません。したがって、つぎのふたつのステートメントは、いずれもランタイムエラーになります[*7]

var myVector:Vector.<Number> = new Vector.<int>();
var myObject:Vector.<DisplayObject> = new Vector.<Sprite>();

Vectorインスタンスのベース型に、Vectorデータ型を指定することもできます。その場合、ベース型として記述したVectorにも、さらにベース型の指定が必要になります。たとえば、ベース型が整数(int)のVectorデータをエレメントとするVectorインスタンスは、つぎのように生成して、変数myVectorに代入できます。

var myVector:Vector.<Vector.<int>> = new Vector.<Vector.<int>>();

Flash Professional CS5から、エレメントを納めたインスタンスの生成がシンタックスとして定められました[*8]。最後のエレメントの後のカンマ(,)は省いて構いません。なお、このシンタックスでは、インスタンスの長さの固定は指定できません。したがって、Vector.fixedプロパティを使って設定します。

new <ベース型>[エレメント0, エレメント1, …, エレメントN, ]

たとえば、0から2までの整数をエレメントとするVectorインスタンスは、つぎのステートメントで生成できます。

var myVector:Vector.<int> = new <int>[0, 1, 2];

Flash CS4 Professionalであっても、Vector()関数で配列を変換すれば、これに近い結果を得ることができます[*9]

var myVector:Vector.<int> = Vector.<int>([0, 1, 2]);

[*5] 一般に型を指定しただけで初期値が与えられていないデータは、デフォルト値として扱われます。ActionScript 3.0で使われるデータ型と、そのデータ型を指定した場合のデフォルト値および取りうる値は、次表01-01-001のとおりです([ヘルプ]の[ActionScript 3.0の学習]<http://help.adobe.com/ja_JP/as3/learn/>/[ActionScript言語とシンタックス]/[データ型]/[データ型の記述]参照)。

表01-01-001■データ型とデフォルト値
データ型 デフォルト値
*(なし) undefined 任意の値
Boolean false trueまたはfalse
int 0 32ビット符号付き整数
Number NaN 64ビット浮動小数点数
String null 16ビット文字列
uint 0 32ビット符号なし整数
void undefined undefined
クラス(リファレンス型データ) null クラスのインスタンス

[*6] Vectorインスタンスの長さを変えるときに処理の負荷が上がるようです。したがって、コンストラクタの第1引数で長さを渡しておくだけでも、エレメントの初期値を加える処理は最適化されます。配列(Array)と、Vectorインスタンスのデフォルトおよび長さの指定とさらに固定した場合の都合4つの処理時間を、wonderflのサンプルスクリプトで比べてみました。

[*7] Vector()グローバル関数を使って、ベース型を変換することはできます。たとえば、つぎのステートメントは、Vector型の各変数にベース型が正しく変換されたVectorインスタンスを代入します。

var myVector:Vector.<Number> = Vector.<Number>(new Vector.<int>());
var myObject:Vector.<DisplayObject> = Vector.<DisplayObject>(new Vector.<Sprite>());

[*8] Vectorエレメントの記述は省くことができません。たとえば、つぎのステートメントは[コンパイルエラー]になります。

var myVector:Vector.<int> = new <int>[0, , 2];

[*9] 違いは、Vector()関数がエレメントを変換することです。

var myVector:Vector.<int> = Vector.<int>([null, 1.1, 2]);
trace(myVector);   // 出力: 0,1,2

new演算子を使った記述では、エレメントがベース型と合わなければ、コンパイルエラー#1215が生じます。

var myVector:Vector.<int> = new <int>[1.1];   // コンパイルエラー

ただし、[strictモード]を外せば(前出注[*3]参照)、暗黙の変換が行われます。

Vectorエレメントの操作
Vectorエレメントの設定および取得は、配列と同じく配列アクセス演算子([])を使って行えます。また、Vectorクラスのメソッドにも、Arrayと同じようにエレメントの値を設定あるいは取得できるものがあります。たとえば、push()pop()shift()unshift()などのメソッドです。ただし、コンストラクタの第2引数にtrueが指定された、長さの変えられないVectorインスタンスには、長さの変更をともなうこれらのメソッドは用いることができません。

たとえば、Vector.push()メソッドや配列アクセス演算子[]を使って、Vectorインスタンスのエレメントをつぎのように設定したり、取得することができます。

var myVector:Vector.<int> = new Vector.<int>();
myVector.push(0);
myVector.push(2);
myVector[1] = 1;
trace(myVector.length);   // 出力: 2 ←インスタンスの長さ
// myVector[5] = 5;     // インデックスが長さを超えるためエラー
var n:int = myVector[0];
// var my_str:String = myVector[1];   // データ型が一致しないためエラー

Vectorインスタンスのエレメントは密(連番)でなければなりませんので、インスタンスの長さつまりVector.lengthプロパティの値より大きなインデックスにエレメントを設定することはできません。また、Vectorインスタンスから取出されたエレメントは、ベース型で指定したデータ型の値として扱われます。

Vector.push()Vector.unshift()メソッドによりVectorにエレメントを加えるとき、引数の値のデータ型はコンパイル時には確認されません。そして、ランタイム(実行時)に、引数値をVectorインスタンスのベース型に変換しようとします。その結果、成功すればその値をエレメントとして加え、変換できないときには「強制型変換に失敗」した旨のランタイムエラーを返します[*10]

前述(「Vectorクラスのコンストラクタメソッドとデータ型指定」)のとおり、Vector()コンストラクタにはエレメントの値を引数として渡すことはできません。したがって、Arrayクラスのようにコンストラクタからは、エレメントをもったインスタンスはつくることができないのです。

けれども、Vector()グローバル関数(前出注[*7])を使えば、リテラル記述の配列をVectorインスタンスに変換することができます。つまり、予めエレメントの備わったVectorインスタンスを、1行の記述で生成することが可能です。たとえば、つぎのステートメントにより、ベース型を整数とする3つのエレメントの備わったVectorインスタンスが生成できます(図002)。

var myVector:Vector.<int> = Vector.<int>([0, 1, 2]);

図002■整数の配列をベース型が整数のVectorインスタンスに変換

[*10] ベース型を数値や文字列などのプリミティブ型で指定した場合は、変換すべき適切な値がなければベース型データのデフォルト値にしてしまうようです。そのため、データ型の一致しない値をメソッドの引数に指定しても、ランタイムエラーは発生しません。

たとえば、ベース型として整数(int型)を指定したVectorインスタンスに、Vector.push()メソッドで引数に文字列の数字を渡せば数値に、オブジェクト(たとえばSpriteインスタンス)を渡すと整数値のデフォルト0がエレメントとして加えられます(図003)。

図003■ベース型が整数の場合文字列の数字は数値にオブジェクトは整数0に変換

参考
[ActionScript 3.0 Reference for the Adobe Flash Platform] > [Vector][*11]

[*11] Vectorクラスについては、ほかにつぎのようなサイトの情報が参考になります。Francis Cheng「Vectors in ECMAScript 4」、「Type Parameters in ECMAScript 4th Edition」、BeInteractive!「FlashPlayer10のVectorについて分かっていることまとめ」、「FlashPlayer10のVectorについて更に色々」、閃光的網站・弛緩複合体「[Astro] Vector クラス(1)」〜。


作成者: 野中文雄
更新日: 2011年2月14日 注[*5]を加えた。
更新日: 2010年6月19日 注[*6]の説明とサンプルを変更。
更新日: 2010年4月24日 注[*6]にwondderflのサンプルを加えた。
更新日: 2010年4月15日 Flash Professional CS5の新たなシンタックスを加え、若干の細かな修正を行った。
更新日: 2009年3月1日「Vectorエレメントの操作」を中心に補足。
作成日: 2009年2月28日 FN0810001を全面改訂。


Copyright © 2001-2010 Fumio Nonaka.  All rights reserved.