数值for循环
for init,max/min,setp do statement(s) end
- 例子:
for i = 1, 3, 1 do print(i) end // 1,2,3
泛型for循环
for ipairs
遇到有key的无法遍历
local t = { 'A', key = 'B' }; for i, v in ipairs(t) do print('i=' .. i .. ', v=' .. v) end // i=1, v=A
for pairs
有没有key都可以正常打印
local t = { 'A', key = 'B' }; for k, v in pairs(t) do print('k=' .. k .. ', v=' .. v) end // k=1, v=A // k=key, v=B
其实pairs
、iparis
是lua的一个function,并不是lua的关键字,如果你对lua源码熟悉的话,你就会找到这2个函数的注册地方:
- lbaselib.c
static const luaL_Reg base_funcs[] = { {"assert", luaB_assert}, {"collectgarbage", luaB_collectgarbage}, {"dofile", luaB_dofile}, {"error", luaB_error}, {"getmetatable", luaB_getmetatable}, {"ipairs", luaB_ipairs}, // ipairs {"loadfile", luaB_loadfile}, {"load", luaB_load}, {"next", luaB_next}, {"pairs", luaB_pairs}, // pairs {"pcall", luaB_pcall}, {"print", luaB_print}, {"warn", luaB_warn}, {"rawequal", luaB_rawequal}, {"rawlen", luaB_rawlen}, {"rawget", luaB_rawget}, {"rawset", luaB_rawset}, {"select", luaB_select}, {"setmetatable", luaB_setmetatable}, {"tonumber", luaB_tonumber}, {"tostring", luaB_tostring}, {"type", luaB_type}, {"xpcall", luaB_xpcall}, /* placeholders */ {LUA_GNAME, NULL}, {"_VERSION", NULL}, {NULL, NULL} };
迭代器
泛型 for 循环通过一个迭代器函数(ipairs、pairs)
来遍历所有值,你会发现在好多的编程语言里面都有迭代器这个概念,特别是在c++的stl里面,当我们要操作数据结构时,迭代器是高频使用的,还有js语言里面,forEach等,你都会看到迭代器的身影。
迭代器的产生
无论是序列容器还是关联容器,最常做的操作无疑是遍历容器中存储的元素,而实现此操作,多数情况会选用“迭代器(iterator)”来实现。那么,迭代器到底是什么呢?
我们知道,尽管不同容器的内部结构各异,但它们本质上都是用来存储大量数据的,换句话说,都是一串能存储多个数据的存储单元。因此,诸如数据的排序、查找、求和等需要对数据进行遍历的操作方法应该是类似的。
既然类似,完全可以利用泛型技术,将它们设计成适用所有容器的通用算法,从而将容器和算法分离开。但实现此目的需要有一个类似中介的装置,它除了要具有对容器进行遍历读写数据的能力之外,还要能对外隐藏容器的内部差异,从而以统一的界面向算法传送数据。
这是泛型思维发展的必然结果,于是迭代器就产生了。