AS3覚え書き1

ActionScript3の文法についてまとめたものです。

変数の宣言

var:int;
num:Number=1.3;
str:String="abc";

定数

const PI:Number=3.14;

int:整数
Number:数値
String:文字列
Boolean:ブール

文字列型

文字の連結
var str:String = str1 + str2 + ".";
文字列→数字

Numberへのキャスト、parse関数を使います。

Number()
parseInt()
parseFloat()

使い方↓

var str:String = "12";
var i:int = parseInt(str);
i = Number(str);
数値→文字列

toStringメソッドで変換できます。

var x:int =8;
var str:String = x.toString();

演算子

代入演算

===,!==は厳密に同じ、異なるという演算子です。

=,+=,-=,*=,/=,%=,==,!=,>,<,>=,<=,===,!==
比較演算
==,!=,>,<,>=,<=,===,!==
論理演算
&&,||,!

引用符号

""を使います。

str="string";

コメント

//を使います。

// comment

配列

配列を扱うのはArrayクラスです。要素のリストによる初期化と、Arrayクラスのコンストラクタで初期化する方法があります。

var a:Array = [10,20,30];
var b:Array = new Array(10,20,30);
a[2]=40;
配列の要素の追加と削除
var a:Array = [10,20,30];
a.push(40,50); //最後に追加
a.pop(); //最後の要素を削除
a.shift();//最初の要素を削除
a.unshift(70);//最初に要素を追加
多次元配列
var a:Array = [["a","b"],["c","d"],["e","f"]];
a[0][1]="t";

条件分岐

elseif,elseはもちろん省略可

if文
if(条件){
	//処理
}else if(条件){
	//処理
}else{
	//処理
}
switch文
switch(式){
	case 値:
		//処理
		break;
	case 値:
		//処理
		break;
	default:
		//処理
}

繰り返し

for文
for(var i:int=0;i < 3; i++){
	//処理
}
break文
for(var i:int=0;i < 3; i++){
	if(条件){
		break;
	}
}
break outer文

外側のforを抜けることができます。内側のinnerに対応して外側がouterです。

for(var i:int=0;i < 3; i++){
	for(var j:int=0;j < 3; j++){
		if(条件){
			break outer;
		}
	}
}

関数

関数の定義。

function(x:int,y:Number,z:String):int{
	return 0;
}
関数の呼び出し
var i:int = function(2,2.7,"test");
デフォルト引数

デフォルト引数は後ろから定めます。

function(x:int,y:Number=2.3,z:String="a"):int{
	return 0;
}
可変個数引数

"..."部分に可変な個数の引数をいれるとzに引数の値が配列として保存されます。

function(x:int,y:Number, ...z):void{
	//余分な引数は配列zに格納
}

テンプレートメタプログラミング (条件分岐)

条件分岐

コンパイル時に条件分岐を行うためのテンプレートの使い方です。
テンプレート引数にtrueまたはflaseを指定すると、それぞれ100,200が代入されるようにしてみます。

	//テンプレート引数にtrueを入れた場合
	cout << 100 << endl;//100
	//テンプレート引数にfalseを入れた場合
	cout << 200 << endl;//200

まずはtrueバージョンとfalseバージョンのクラスを定義して、数値を分離します。

struct IF_true{
	enum {
		ret= 100
	};
};
struct IF_false{
	enum {
		ret= 200
	};
};
void test{
	//テンプレート引数にtrueを入れた場合
	cout << IF_true::ret << endl;//100
	//テンプレート引数にfalseを入れた場合
	cout << IF_false::ret << endl;//200
}
テンプレート化

さらにtrueとfalseをテンプレート引数にしたクラスを作成します。まずboolをテンプレート引数としたIFクラスを作ります。そのあと引数がtrueとfalseの特殊な場合を定義しておきます。

template <bool Con>
struct IF{
};

template <>
struct IF<true> {
	enum {
		ret = 100
	};
};
template <>
struct IF<false> {
	enum {
		ret = 200
	};
};

利用するときは、テンプレート引数としてtrueまたはfalseを指定します。

cout << IF<true>::ret <<endl;
cout << IF<false>::ret <<endl;

100
200

条件分岐の応用

条件によってさまざまなクラスを呼び出すことができるようにしてみましょう。コンパイル時にテンプレート引数としてtrueを指定したときにはクラスAを、falseを指定したときにはクラスBを展開するようにしてみます。次のようにクラスA,Bでメンバ変数や定数、関数などが定義されているとします。メンバがinline関数やstaticな定数の場合は、処理をコンパイル時に行うことができます。

struct A{	/*クラスAで定義されているもの*/
	static const int val = 10;
	static void statFunc(){ cout << "A...." << endl; }
	void func(){ cout << "A!" << endl; }	//インスタンス化して利用できるinlineメンバ関数
};
struct B{	/*クラスBで定義されているもの*/
	static const int val = 20;
	static void statFunc(){ cout << "B...." << endl; }
	void func(){ cout << "B!" << endl; }	//インスタンス化して利用できるinlineメンバ関数
};
void test(){
	//テンプレート引数にtrueを入れた場合 Aで定義されているものを展開する
	cout << A::val <<endl;	
	A::statFunc();
	A a;
	a.func();
	//テンプレート引数にfalseを入れた場合 Bで定義されているものを展開する
	cout << B::val <<endl;	
	B::statFunc();
	B b;
	b.func();
}

条件によって呼び出すクラスを変化させるには次のようにtypedefを使って定義すれば実現することができます。

struct IF_true{
	typedef A ret;
};
struct IF_false{
	typedef B ret;
};

void test(){
	//テンプレート引数にtrueを入れた場合 Aで定義されているものを展開する
	cout << IF_true::ret::val <<endl;	
	IF_true::ret::statFunc();	
	IF_true::ret trueObj;
	trueObj.func();
	//テンプレート引数にfalseを入れた場合 Bで定義されているものを展開する
	cout << IF_false::ret::val <<endl;	
	IF_false::ret::statFunc();	
	IF_false::ret falseObj;
	falseObj.func();
} 
テンプレート化その1

IF_trueとIF_falseをテンプレート化します。

template <bool Con>
struct IF;

template <>
struct IF<true>{
	typedef A ret;
};
template <>
struct IF<false>{
	typedef B ret;
};

trueの場合の利用例は下のようになります。

	cout << IF<true>::ret::val <<endl;
	IF<true>::ret::statFunc();			
	IF<true>::ret Obj;
	Obj.func();

falseを入れた場合も同様です。

	cout << IF<false>::ret::val <<endl;	
	IF<false>::ret::statFunc();			
	IF<false>::ret Obj;
	Obj.func();
テンプレート化その2

上の例では、trueのときはクラスA、falseのときはクラスBしか展開できません。いわばクラスAとB専用のIFなので改めてIF_ABと書くことにします。これをさらに拡張して、どんなクラスでも展開できるようにしてみましょう。

template <bool Con>
struct IF_AB;

template <>
struct IF_AB<true>{
	typedef A ret;
};
template <>
struct IF_AB<false>{
	typedef B ret;
};

クラスそのものをテンプレート引数にすれば全てのクラスに対応することができます。

template <bool Con, class Then,class Else>
struct IF;

template <class Then,class Else>
struct IF<true,Then,Else>{
	typedef Then ret;
};
template <class Then,class Else>
struct IF<false,Then,Else>{
	typedef Else ret;
};
	//条件分岐の対象クラスをA,Bに設定して、テンプレート引数にtrueを入れた場合
	cout << IF<true,A,B>::ret::val <<endl;
	IF<true,A,B>::ret::statFunc();			
	IF<true,A,B>::ret Obj;
	Obj.func();

10
A....
A!
class Thenやclass Elseにはintやfloatなどの型を入れることもできるので、例えばテンプレート引数の条件分岐によってunsigned charまたはshortの変数を用意するコードを記述することもできます。

	IF<true,unsigned char, short> waveData[100];