First agree to the definition: (in Lua) an iterator is a function-like object that returns the next value in the sequence for each call. I think this will help rewrite the iteration foras done in the Lua ref manual:
for itemlist in expression do block end
logically equivalent (pseudo-code):
do
local func, seq, controlVar = expression
while true do
local itemlist = func(seq, controlVar)
if first of itemlist == nil then break end
controlVar = first of itemlist
block (which uses items in itemlist)
end
end
where expressionis the data triplet (or a function call that returns such a triplet):
func - actual iterator functionseq - ,controlVar -
- , , . , , func : func(seq, controlVar), ( seq ); , .
, Lua . , , . I.e., " s" "(s, controlVar)" . ipairs() , : ipairs(s) (iterFunction, s, 1); iterFunction s 1 2, s[1], 3, s[2] .. ( nil, s[N] N ).
, ? , ? :
, . Lua , ( upvalues) (, , .. __call). () () .
. ipairs:
function statefulIpairs(s)
local f, s, var = ipairs(s)
return function()
local i, v = f(s,var)
var = i
return i, v
end
end
tbl = {'a', 'b', 'c', 'd'}
sip = statefulIpairs(tbl) -- sip is stateful iter specific to tbl
for i,v in sip() do print(i,v) end
, : API- , . : . , , , non nil, :
function resetableStatefulIpairs(s)
local f, s, var = ipairs(s)
local start = var
return function(a,b,reset)
if reset ~= nil then var = start; return end
local i, v = f(s,var)
var = i
return i, v
end
end
sip = resetableStatefulIpairs(tbl)
for i,v in sip() do print(i,v) end
sip(nil, nil, true)
for i,v in sip() do print(i,v) end
. , , "... 3 " ( @deduplicator):
function iterGen(seq, start)
local cvar = start or 1
return function(cmd)
if cmd == nil then
if cvar >
val = seq[cvar]
cvar = cvar + 1
return cvar-1, val
else
cmd = cmd[1]
if cmd == 'rewind' then
cvar = start or 1
elseif cmd == 'newstart' then
start = cvar
end
end
end
end
:
> s = {1,2,3,4,5,6,7}
> iter = iterGen(s)
> for i,v in iter do print(i,v); if i==3 then break end end
1 1
2 2
3 3
> iter {'newstart'} -- save current as the new start pos
> for i,v in iter do print(i,v) end -- continue till end
4 4
5 5
6 6
7 7
> iter {'rewind'}
> for i,v in iter do print(i,v) end
4 4
5 5
6 6
7 7
> iter {'rewind'}
> for i,v in iter do print(i,v) end
4 4
5 5
6 6
7 7
, , , , , , , newstart . .
API- , "" "", , .