1, iterators and closure
In Lua, iterators are usually functions, and each time a function is invoked, the next element in the collection is returned. Each iterator needs to save some state when it is successfully invoked, and the closure (closure) is perfect for use by iterators.
Copy Code code as follows:
function values (t)
Local i=0
return function ()--anonymous function
I=i+1
return T[i]
End
End
T1 ={10, 20, 30}
It=values (T1)--Create a parameter for a closure variable as a function argument
While True
Local Element=it ()--parameter to anonymous function when the closure is invoked
if (Element==nil) then break
End
Print (Element)
End
T2={11,22,33}
For V in values (T2) do
Print (v)
End
--Output results
--10
20th
--30
--11
--22
--33
As can be seen from the example above, the paradigm for the while provides us with a clearer implementation logic. The intrinsic function of Luo has provided us with an iterative function, and we call an implicit iterator when we run foreach.
2, generic for semantics
The above iterator has an obvious disadvantage, is to create a new closure variable for Each loop, instead of using the closure variable that was previously created, this is a cumbersome and error-prone issue if I iterate over the loop for an iterative iteration.
The iterator that appears below solves this problem well without creating a new closure variable for each generic for.
Copy Code code as follows:
function iter (a,i)
I=i+1
If A[i]==nil then return Nil,nil
else return I,a[i]
End
End
function Ipairs (a)
Return iter,a,0--iter Here is just a function variable, not calling a function
End
a={"One", "two", "three"}
For i,v in Ipairs (a) do
Print (I,V)
End
--The above generic for can be changed to the following while notation
Todo
Local _it,_s,_k=ipairs (a)
While True
K,v=_it (_s,_k)
_k=k
If K==nil then break end
Print (K,V)
End
End
--Output results
--1 One
--2 Two
--3 Three
--1 One
--2 Two
--3 Three
3, no State iterator
Copy Code code as follows:
function GetNext (List,node)
If not node then return list
else return Node.next
End
End
function traverse (list)
Return Getnext,list,nil
End
List=nil
For line in Io.lines () do
List={next=list, Value=line}
End
For node in traverse (list) do
Print (Node.value)
End
--Input
--a
--b
--c
--Output
--c
--b
--a
As you can see from the example above, you can use the list variable infinitely and invoke the Traverse function without creating a new closure variable before each loop, as in the first case.