As we learned in the previous sections, the while and repeat control structures allow a program to loop over a block of code until a specified condition is met. These are sometimes called "condition-controlled" loops.
Another common loop is called a "count-controlled" loop, in which the loop iterates a specified number of times. In Lua, this type of loop is called the "Numeric For Loop".
The general pattern for the numeric for loop is:
for [var] = [start], [stop], [step=1] do
-- loop body
-- repeat for each specified iteration
end
where var is an arbitrary variable name that is locally-scoped to the loop body, and the start, stop, and (optional) step parameters define "how" the loop will execute.
Loop execution can be more easily understood by considering it to proceed in two parts, which we could call initialization and iteration.
Initialization
When the Lua encounters a for loop, the first thing it does is evaluate each of the start, stop, and (optional) step expressions, which are used to generate a sequence of numbers that will define:
-
How many times the loop body will execute, and
-
What values will be assigned to var prior to each iteration of the loop.
Each number in the generated sequence will be assigned to var, one by one, until the sequence is exhausted. The first number in the loop is the value assigned to start, then the second number is start + step, then the third in start + 2 * step, and so on:
var = start
var = start + 1 * step -- first iteration
var = start + 2 * step -- second iteration
var = start + 3 * step -- third iteration
...
var = start + n * step -- nth iteration
This list continues for n steps, until start + n * step >= stop. When step is not specified, it is assigned a default value of 1.
Iteration
Now that we have initialized the loop, we can move to the iteration step. In this step, the loop body is execute once for each value of var in the "iteration list". The main point of this step is to define the loop body so that it performs the correct operations given each value of var.
Examples
Let's take a look at a few examples:
Example 1
In the first example, let's consider a simple loop that counts from 0 to 5:
for x = 0, 5 do
print("x = " .. x)
end
When executed, this loop generates the following output:
x = 0
x = 1
x = 2
x = 3
x = 4
x = 5
Example 2
As a second example, let's pick another simple with a step value of 2:
for x = 0, 10, 2 do
print("x = " .. x)
end
This loop behaves similarly to the previous example, except for the value assigned the x
.
x = 0
x = 2
x = 4
x = 6
x = 8
x = 10
Example 3
Finally, as a final example, let's look at a slightly more complicated case that requires the stop and step parameters to be evaluated prior to generating the sequence of values to iterate over:
for x = 0, 2 * 3.14, 3.14 / 2 do
print("x = " .. x)
end
Although the mechanics of generating the loop values is slightly different, loop operation remains basically the same:
x = 0.0
x = 1.57
x = 3.14
x = 4.71
x = 6.28
Early Termination
Although the basic operation of the numeric for loop is to repeat the loop body for a
pre-determined number of iteration, it is possible to terminate the loop early if needed. This is
generally done using break
, although a loop inside of a function can also
terminate early when a return
is encountered:
break
In order to demonstrate break
we will use the following shamefully-contrived example. In this
example, the loop parameters call for iterating the loop 6 times, but the loop body contains code to
terminate the loop early if a specific condition is encountered:
for x = 0, 5 do
if x == 3 then
break
end
print("x = " .. x)
end
When this loop executes, it generates the following output:
x = 0
x = 1
x = 2
This is obviously a contrived example, but shows a pattern that can be helpful in cases where the loop parameters define the maximum number of times that the loop will iterate, while containing additional logic enforcing condition under which the loop should terminate early.
return
As with the "condition-controlled" loops we look at previously, the return
statement can also be
used terminate a "numeric for" loop early when operating inside a function. The following code
demonstrates this with a similar implementation:
local function count()
for x = 0, 5 do
if x == 3 then
return
end
print("x = " .. x)
end
end
count()
which produces the following output:
x = 0
x = 1
x = 2