1. iterator and Closure
In Lua, The iterator is usually a function. Every time the iterator function is called, The next element in the set is returned. When each iterator is called successfully, it needs to save some States. Closure (closure) is perfect for the iterator application.
Function values (t) Local I = 0 return function () -- anonymous function I = I + 1 return T [I] endendt1 = {10, 20, 30} It = values (T1) -- the parameter for creating the closure variable is the function parameter while true do local element = it () -- When the closure is called, the parameter is the IF (element = nil) Then break end print (element) endt2 = {11, 22, 33} for V in values (T2) parameter of the anonymous function) do print (v) end -- output result -- 10--20--30--11--22--33
From the above example, we can see that compared with while, the model for provides us with a clearer implementation logic. Luo's internal functions provide iterative functions for us. When running foreach, we call the implicit iterator.
2. Semantics of generic
The previous iterator has an obvious drawback, that is, a new closure variable should be created every cycle, instead of using the previously created closure variable, if I add a loop out of this loop for iteration, this becomes a very tedious and error-prone problem.
The following iterator solves this problem well, so it is not necessary to create a new closure variable for every generic for operation.
Function ITER (A, I) I = I + 1 if a [I] = nil then return nil, nil else return I, a [I] endendfunction ipairs () return ITER, A, 0 -- ITER is just a function variable here, not calling the function ENDA = {"one", "two", "three"} For I, V in ipairs (a) Do print (I, V) end -- the above generic for statement can be changed to the following while statement: Do Local _ it, _ s, _ k = ipairs (a) While true do K, V = _ It (_ s, _ k) _ k = K if k = nil then break end print (K, v) endend -- output result -- 1 one -- 2 two -- 3 three -- 1 one -- 2 two -- 3 three
3. Stateless iterator
Function getnext (list, node) if not node then return list else return node. next endendfunction traverse (list) return getnext, list, nilendlist = nilfor line in Io. lines () Do list = {next = List, value = line} endfor node in Traverse (list) Do print (node. value) end -- input -- a -- B -- c -- output -- c -- B --
The preceding example shows that you can use the list variable and call the traverse function infinitely without creating a new closure variable before each loop, as in the first case.
Lua iterator and generic