I already know the while
, repeat
and for
ties, but when I was looking at the types of loops, in the section I found the "Loop for
generic" section. The text was in English.
I already know the while
, repeat
and for
ties, but when I was looking at the types of loops, in the section I found the "Loop for
generic" section. The text was in English.
The version 5.2 manual has a Portuguese version, whose relevant part I quote below :
The generic for command works by using functions, called iterators . At each iteration, the iterator function is called to produce a new value, stopping when that new value is nil . The for generic loop has the following syntax:
end list inlistanomes :: = Name ',' Name}
A for command as
for var1, ..., varn in listaexps do bloco end
is equivalent to the code:
do local f, s, var = listaexps while true do local var1, ..., varn = f(s, var) if var1 == nil then break end var = var1 bloco end end
Note the following:
- listaexps is evaluated only once. Its results are an iterator function, a state , and an initial value for the first iterator variable .
- f , s , and var are invisible variables. The names are here for educational purposes only.
- You can use break to exit a for link. The variables var var are local to the loop; you can not use their value after the for end. If you need these values, then assign them to other variables before breaking or leaving the loop.
So, commenting:
The in and expression in for generic is a triplicate; the first element is a function, the second is an auxiliary value, and the third is the iteration index.
At the time of iterating, the function that is the first element of the triplet will be called with the other two elements as parameters. The second element is constant throughout the loop, and often is the collection being iterated. The third one is the current element or index, and will be used by the function to decide which next element to return.
For example, let's look at an iterator like pairs(table)
: If you run in REPL demonstration of lua.org :
> print(pairs(io))
You will get back something like the following:
function: 0x41b980 table: 0x22d2ca0 nil
That is, a function, a table, and a nil
. Doing:
> local f, t, n = pairs(io)
> print((f == next), (t == io), n)
true true nil
You find that the function that pairs()
returned is next()
and the object is the io
table that it received as a parameter. Saying:
> next(io, nil)
write function: 0x41de30
> next(io, 'write')
nil
You go through the elements of the io
table (which only contains one item in that environment, called write
). This execution of next()
is like running the loop "in the hand"; what is does is to simply pass the results of next
to the body of the loop in the order that it receives them.