直接上代码,实现lua的ipairs函数
local global_t = {"one", "two", "three", "four"}
local v
local iter = function(lvTable, k)
k = k + 1
v = lvTable[k]
if v then
return k, v
end
end
function ipairs_test(lvTable)
return iter, lvTable, 0
end
for k, v in ipairs_test(global_t) do
print(k, "-->", v)
end
lua调用ipairs函数时,会获取到三个参数,一个迭代器函数,一个table,一个起始值(默认是0)。
然后,调用iter(a, 0),返回对应的key,value。
这个迭代器不同于使用闭包实现的迭代器,不需要迭代器保存状态,所以也被称为无状态迭代器。
使用闭包实现的迭代器如下:
function closure(t)
local i = 0 --这里保存了状态
return function()
i = i + 1
if t[i] then
return i, t[i]
end
end
end
for k, v in closure(global_t) do
print(k, "->>", v)
end
--while true的实现方法
function closureEx(t)
local i = 0
local n = table.getn(t)
return function()
i = i + 1
if i <= n then
return i, t[i]
end
end
end
local closureImp = closureEx(global_t)
local key
local value
while true do
key, value = closureImp()
if not value then break end
print(key, "-->>", value)
end
pairs函数实现:
function pairs(t)
return next, t, nil
end
其中,next函数是lua使用c代码实现的内部函数。lua调用pairs函数时,向next迭代器函数传入table和key,然后next函数会返回value。
接着,我们在抠一下next函数如何实现的。
LUA_API int (lua_next) (lua_State *L, int idx);
没有实现代码,只有lua提供的迭代器范例伪代码:
/* table is in the stack at index 't' */
lua_pushnil(L); /* first key */
while (lua_next(L, t) != 0) {
/* uses 'key' (at index -2) and 'value' (at index -1) */
printf("%s - %s\n",
lua_typename(L, lua_type(L, -2)),
lua_typename(L, lua_type(L, -1)));
/* removes 'value'; keeps 'key' for next iteration */
lua_pop(L, 1);
}
首先,在栈顶推入一个nil,作为第一个key,然后调用lua_next方法迭代,最后再推出栈顶值。这么泛泛而谈其实很难搞懂,再往下走:
查一下lua的手册(http://manual.luaer.cn/lua_next.html)。
虽然还是没有给出代码,但是提供了解释:
意思是:先从栈上弹出一个 key(键),然后把索引指定的表中 key-value(健值)对压入堆栈(指定 key 后面的下一 (next) 对)。如果表中没有任何键值了,那么返回0以结束。