foreach 文

配列内の要素を列挙し、それぞれの要素を使用して反復処理を行います。


taiseiue | 2023-08-07

定義

名前空間: Alice
アセンブリ: Losetta.Runtime.dll
ソースコード: Alice.Core.Flow.cs

配列内の要素を列挙し、それぞれの要素を使用して反復処理を行います。

AliceScript
namespace Alice;
public void foreach(Expression define in object iterator)
{
    //...
}
引数
define 要素を代入する変数の宣言式
iterator 反復処理を行う対象のオブジェクト。ただしGetEnumeratorメソッドを適切に実装している必要があります。

対応
AliceScript RC1、RC2、GM、2.0、2.1、2.2、2.3、3.0、4
AliceSister GM、2.0、2.1、2.2、2.3、3.0、4
Losetta 0.8、0.9、0.10、0.11

基本

foreach文は、配列型の各要素をひとつづつ取り出して、本文の処理を行います。 次の例では、配列aryに定義されている要素全て表示します。

AliceScript
var ary = [2, 4, 6, 8, 10];
foreach(var element in ary)
{
    print(element);
}
//出力例:
//2
//4
//6
//8
//10

foreach文がfor文と異なるところは、インデックスを使ってアクセスできないようなオブジェクトに対しても列挙を行えることです。iteratorは、GetEnumeratorメソッドを適切に実装していればforeach文を実行できます。GetEnumeratorメソッドを実装していないか、IEnumeratorオブジェクトを返さない場合は、「foreachでループするオブジェクトは適切にGetEnumeratorメソッドを実装する必要があります」というエラーが発生します。条件を満たす場合、論理的にはforeach文は以下のようなコードに展開されます。

AliceScript
var ary = [2, 4, 6, 8, 10];

try
{
    var enumerator = ary.GetEnumerator();

    while(enumerator.MoveNext())
    {
        var element = enumerator.Current;

        print(element);
    }
}
finally
{
    enumerator.Dispose();
}

ただし、パフォーマンス上の観点から、配列型および文字列型は以下のようなコードに展開されます。

AliceScript
var ary = [2, 4, 6, 8, 10];

for(number i = 0; i < ary.Length; i++)
{
    readonly var each_const = ary[i];

    print(element);
}

要素の過不足があった場合には、0x029エラーが、「foreach文はforeach(variable in array)の形をとるべきです」というメッセージで発生します。