制御構造

拡張関数言語には、プログラムの実行を制御する通常のステートメントが用意されています。

  • もしそうなら
  • 実行しながら繰り返す
  • 数値形式
  • ブレーク
  • Goto

もしそうなら

If ステートメントは、1 つ以上の条件に基づいて実行するステートメントのブロックを選択します。次の 3 つの形式があります。

If then Form

if expression then
     statements to execute if expression is not false or nil
end
<!--NeedCopy-->

If then else Form

if expression then
     statements to execute if expression is not false or nil
else
     statements to execute if expression is false or nil
end
<!--NeedCopy-->

If then elseif else Form

if expression1 then
     statements to execute if expression1 is not false or nil
     elseif expression2 then
          statements to execute if expression2 is not false or nil
. . .
else
     statements to execute if all expressions are false or nil
end
<!--NeedCopy-->

例:

if headers[name] then

     local next_value_index = #(headers[name]) + 1
     headers[name][next_value_index] = value

else

     headers[name] = {name .. ":" .. value}

end
<!--NeedCopy-->

注:

  • C や Java の場合のように、式は括弧で囲まれていません。
  • C/Java スイッチステートメントと同等のものはありません。同等の処理を行うには、一連の if elseif ステートメントを使用する必要があります。

実行しながら繰り返す

while ステートメントと repeat ステートメントでは、エクスプレッションによってループを制御できます。

while expression do
     statements to execute while expression is not false or nil
end

repeat

     statements to execute until expression is not false or nil

until expression
<!--NeedCopy-->

while の例:

local a = {1, 2, 3, 4}
local sum, i = 0, 1 -- multiple assignment initializing sum and i
while i <= #a do -- check if at the end of the array
     sum = sum + a[i] -- add array element with index i to sum
     i = i + 1 -- move to the next element
end
<!--NeedCopy-->

リピートの例:

sum, i = 0, 1 -- multiple assignment initializing sum and i
repeat
     sum = sum + a[i] -- add array element with index i to sum
     i = i + 1 -- move to the next element
until i > #a -- check if past the end of the array
<!--NeedCopy-->

もちろん、これらの例のいずれかでi = i + 1ステートメントを省略した場合など、終了しないループを書くことも可能です。このような関数が実行されると、NetScalerはその関数が妥当な時間内に完了しなかったことを検出し、実行時エラーを出して強制終了します。

Cpu limit reached. Terminating extension execution in [[string "function extension function..."]]: line line-number.

/var/log/ns.log にレポートされます。

数値形式

for ループには 2 つのタイプがあります。1 つ目は数値の for です。これは C や Java で通常の for 文の使い方と似ています。numeric for ステートメントは変数を初期化し、変数が最終値を渡したかどうかをテストします。渡されなかった場合は、ステートメントのブロックを実行して変数をインクリメントして繰り返します。数値の for ループの構文は以下のとおりです。

for variable = initial, final, increment do

     statements in the loop body

end
<!--NeedCopy-->

ここで、initial、final、およびincrementはすべて数値を生成する (または数値に変換できる) 式です。variableはforループステートメントブロックのローカルと見なされ、ループ外では使用できません。incrementは省略できます。デフォルトは1です。式はループの開始時に 1 回評価されます。終了条件は、インクリメントが正の場合は変数 > final で、インクリメントが負の場合は変数 < final です。インクリメントが 0 の場合、ループはすぐに終了します。

例 (前のセクションの while ループと repeat ループと同等):

sum = 0
for i = 1, #a do -- increment defaults to 1
     sum = sum + a[i]
end
<!--NeedCopy-->

for ループの 2 番目のタイプは汎用の for で、より柔軟なタイプのループに使用できます。これには関数の使用が含まれるため、関数が導入された後に説明します。

ブレーク

break ステートメントは while、repeat、for ループの中で使用します。ループを終了し、ループの後の最初のステートメントで実行を再開します。例 (前述の while ループ、repeat ループ、for ループと同等です):

sum, i = 0, 1
while true do
     if i > #a then
          break
     end
     sum = sum + a[i]
     i = i + 1
end
<!--NeedCopy-->

Goto

goto ステートメントを使用すると、ラベルに移動したり戻ったりできます。ラベルは識別子で、構文は:: label:: です。goto ステートメントは goto ラベルです。例 (ここでも前述のループと同等):

sum, i = 0, 1
::start_loop::
     if i > #a then
          goto end_loop -- forward jump
     end
     sum = sum + a[i]
     i = i + 1
     goto start_loop -- backwards jump
::end_loop::
. . .
<!--NeedCopy-->

プログラミングでgotoを使うことについては、長い間論争が続いています。一般的には、関数を読みやすく信頼性のあるものにするために、他の制御構造を使用するようにしてください。しかし、ときどきgotoを賢く使うことで、より良いプログラムにつながるかもしれません。特に、gotosはエラーの処理に役立ちます。

制御構造