for (マクロ)
パッケージ: CURL.LANGUAGE.COMPILER

一般的な目的のループ構成。

説明

for ループには、数値の範囲を繰り返し処理するループとコンテナ オブジェクトを繰り返し処理するループの 2 種類があります。ループの種類は、intodowntobelow、または above のどのキーワードを使用するかによって決まります。in はコンテナのループに使用され、その他は数値範囲のループに使用されます。next キーワードは両方のタイプの for ループで使用できます。next 句の使用方法の詳細につしては、while を参照してください。
  • 範囲ループ。範囲ループは、数値の範囲を繰り返し処理します。各範囲ループは開始値と終了値を持ち、オプションで、各ループでループ カウンタをどれだけ増加/減少させるかを指定する step を持ちます。step が指定されていない場合、既定値は 1 です。
    例:
    {for x=0 to 2 do
        {f x}
    }
    
    この例では、キーワード to は、"終了値まで含めてループし、毎回 x 値を増分すること" を意味します。このため、このループは、{f 0} を呼び出した後に、{f 1} を呼び出し、最後に {f 2} を呼び出します。
    すべての値のうち、最後の値のみ含めないようにするには、to の代わりに below を使用します。同様に、逆の順序でループさせる場合は、downto (終了値を含む) と above (終了値を含まない) を使用します。
    step キーワードを使用してオプションのステップを指定できます。
    {for x:int=4 to 8 step 2 do
        {f x}
    }
    
    この例では、{f 4}{f 6} を呼び出してから {f 8} を呼び出します。tobelow ではステップが加算され、downtoabove ではステップが減算されます。このため、正の数でないステップは通常、エラーとなります。そして、Decimal型の正の数でないステップは、実行時エラーとなります。
    ループ変数の型が指定されていない場合は、開始値のデータ型から適用されます。
  • コンテナ ループ。キーワード in は、コンテナ オブジェクトのループを指定します。単純な例として、次のループは fmy-array の各要素で呼び出します。
    {for x in my-array do
        {f x}
    }
    
    サンプル ループは、StringHashTable-of、列挙型、その他の様々なオブジェクトで機能します。for が繰り返し処理可能な独自のオブジェクトを作成する方法については、「注意」を参照してください。
    key キーワードを使用して、コンテナへのすべての "キー" をループすることも可能です。たとえば、これはハッシュ テーブル内のすべてのキーをループします。
    {for key k in my-hashtable do
        {f k}
    }
    
    通常のループ変数に加えて、key キーワードを使用することができます。この例は、ハッシュ テーブル内のキーと値の両方を同時にループします。
    {for v key k in my-hashtable do
        {f v, k}
    }
    
    key は、配列など単純なインデックスされたコンテナに対しても動作する一般的な概念です。配列では、"キー" は配列のインデックスです。したがって、これは配列内のすべてのインデックスを (順番に) ループする便利な方法となります。
    {for key i in my-array do
        set my-array[i] = 0
    }
    
    キーまたは値変数のどちらかの型が指定されない場合は、繰り返し処理されるコンテナの型から適用されます。
    残余引数はコンテナの特殊型で、for で繰り返し処理方法を指定できます。関数の残余引数をすべて繰り返し処理するには次のように記述します。
    {for v in ... do
        {f v}
    }
    
    これは、... 内にどれかのキーワード引数があると、例外をスローします。実際にキーワード引数を受け取る場合は、もっと一般的な形式を使用します。
    {for (v, k) in ... do
        {f k, v}
    }
    
    各キーワード引数について、kがキーワード名 (String) にバインドされます。各非キーワード引数については、knull になります。
for ループは "タグ付き" 可能で、これにより、breakcontinue でそれらが参照するループを指定できます。タグ付きループは、フォーム tag = tag-name句を含みます。ここで tag-name は有効な Curl 識別子です。
{for tag=outer, x=0 to 10 do
    {for y=0 to 10 do
        {if my-array[x, y] == 0 then
            {break tag=outer}
        }
    }
}
for は、正しいメソッドを指定したどのコンテナの繰り返し処理にも使用できます。使用可能なメソッドには、次の 3 つの異なるセットがあります。
  • get メソッドと for-loop-count プロパティの両方。get は単一の整数を引数として取って値を返し、for-loop-count は数値を評価しなければなりません。for がこの両方を検出すると、各インデックスで get を呼び出し、0 から x.for-loop-count - 1 のループを生成し ます。
  • to-Iterator メソッド (key をリクエストしない場合)。これは、Iterator オブジェクトを返し、そのオブジェクトの read-one メソッドが値と eof フラグを返さなければなりません。このようなオブジェクトの例として Iterator-of があります。
  • get メソッドと keys-to-Iterator メソッド (key をリクエストする場合)。keys-to-Iterator は、キー/eof? フラグ ペアのストリームを返さなければなりません。ここで各キーは get メソッドに渡されて値を取得します。
for ループで繰り返しを使用した後、繰り返しを再度使用する前に、Iterator-of.reset を使用してリセットしなければならない点に注意してください。
for は、開始時に一度だけそのパラメータを評価します。ループの各回では評価しません。例 :

例: for パラメータを一度だけ評価
{value
    let my-vbox:VBox = {VBox}
    
    let my-end:int = 8
    let my-step:int = 4
    
    {for i = 0 to my-end step my-step do
        {my-vbox.add i}
        
        || These assignments will have no
        || effect on the loop, because
        || "for" already determined the
        || end and step values.
        set my-step = 1
        set my-end = 1000
    }
    
    my-vbox
}
while ループと同様に、for ループには、next 句をいくつでも含めることが可能です。詳細については、while および continue を参照してください。

  • これは数値 0、1、2、3 を繰り返し処理し、各値で関数 f を呼び出します。
    {for x=0 to 3 do
        {f x}
    }
    
  • これは数値 3、2、1、0 を繰り返し処理します。
    {for x=3 downto 0 do
        {f x}
    }
    
  • これは数値 -4、-2、0、2、4、6、8 を繰り返し処理します。
    {for x=-4 below 10 step 2 do
        {f x}
    }
    
  • これは、0 が "above 10" でないために即時にループから出ます。
    {for x=0 above 10 do
        {f x}
    }
    
  • これは、my-array 内のすべての要素を順番にループします。
    {for x in my-array do
        {f x}
    }
    
  • これは、各要素の配列インデックスを y 内に格納しながら my-array 内のすべての要素をループします。
    {for x key y in my-array do
        {f x, y}
    }
    
  • これは、列挙型の値 Fruit をループし、各値で関数 eat を呼び出します。
    {define-enum Fruit apple, orange, pear}
    {for fruit in Fruit do
        {eat fruit}
    }
    
『Curl 開発者ガイド』で for のセクションも参照してください。

注意事項

Curl プログラマの中でも、Java、C 言語、C++、およびそれら関連言語に精通したプログラマには、Curl 言語における C 言語スタイルの for ループ動作の表現方法は興味深いでしょう。
一般的に C 言語スタイルの for ループは以下のように記述されます。
for {init; condition; reset} body ;
Curl で表現する場合は次のようになります。
{do
  init
  {while condition do
    body
   next
    reset
  }
}
一番外側の do は、initlet ステートメントが含まれないか、init に定義された変数のスコープに制約がなければ、省くことができます。next キーワードは、bodycontinue ステートメントが含まれないか、reset が空の場合、省くことができます。