JavaScript
Haxe

Haxeのfor文を正しく理解する。

More than 5 years have passed since last update.

Haxeには、Java,C,AS3のような通常のfor文がありません。

iを0からlength-1までループさせたい場合。

for( i in 0...length ) {}

と書きます。


ダメな例

for(i = 0; i < length; i++) {}


は使えません。

あまり見ないfor文なので、どういう挙動をするか具体的に確認しておきます。


できないこと

逆順ループは出来ません。


Main.hx

class Main {

static function main() {
for ( i in 20...0 ) {} //エラー
}
}

ループ中にカウンタ変数の変更はできません。


Main.hx

class Main {

static function main() {
for ( i in 0...20 ) {
i++; //エラー
}
}
}


終値について

終値は変更可能です。


Main.hx

class Main {

static function main() {
var length:Int = 10;
for ( i in 0...length ) {
length = 5;
}
}
}

↓JavaScriptに出力してみます。


Main.js

var Main = function() { }

Main.main = function() {
var length = 10;
var _g = 0;
while(_g < length) {
var i = _g++;
length = 5;
}
}
Main.main();

ただし、フィールド変数の変更はループ回数に反映されません。


Main.hx

class Main {

static var len:Int = 10;
static function main() {
for ( i in 0...len ) {
len = 5;
}
}
}


Main.js

var Main = function() { }

Main.main = function() {
var _g1 = 0, _g = Main.len;
while(_g1 < _g) {
var i = _g1++;
Main.len = 5;
}
}
Main.len = 10;
Main.main();

配列の長さも反映されません。


Main.hx

class Main {

static function main() {
var arr = [0,1,2,3];
for ( i in 0...arr.length ) {
arr.pop(); //配列を1つ短くする。
}
}
}


Main.js

var Main = function() { }

Main.main = function() {
var arr = [0,1,2,3];
var _g1 = 0, _g = arr.length;
while(_g1 < _g) {
var i = _g1++;
arr.pop();
}
}
Main.main();

ここら辺は速度重視みたいですね。


その他

中断できます。


Main.hx

class Main {

static function main() {
for ( i in 0...20 ) {
break; //ココでループを中断。
}
}
}

continueもできます。


Main.hx

class Main {

static function main() {
for ( i in 0...20 ) {
continue;
//continue以下は実行されず次のループに入ります。
}
}
}

いわゆるForeach文のような使い方もできます。


Main.hx

class Main {

static function main() {
var arr = ["Hello","World","!","!"];
for ( str in arr ) {
trace( str ); //「Hello」「World」「!」「!」が順番に出力。
}
}
}

オブジェクトのプロパティでループさせることもできます。

(AS3のfor-inループに当たります)


Main.hx

class Main {

static function main() {
var o = { x:10, y:20 };
for ( key in Reflect.fields( o ) ) {
trace( key ); //「x」「y」が出力。
trace( Reflect.field(o, key) ); //「10」「20」が出力。
}
}
}