开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 4 天,点击查看活动详情
数值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)”来实现。那么,迭代器到底是什么呢?
我们知道,尽管不同容器的内部结构各异,但它们本质上都是用来存储大量数据的,换句话说,都是一串能存储多个数据的存储单元。因此,诸如数据的排序、查找、求和等需要对数据进行遍历的操作方法应该是类似的。
既然类似,完全可以利用泛型技术,将它们设计成适用所有容器的通用算法,从而将容器和算法分离开。但实现此目的需要有一个类似中介的装置,它除了要具有对容器进行遍历读写数据的能力之外,还要能对外隐藏容器的内部差异,从而以统一的界面向算法传送数据。
这是泛型思维发展的必然结果,于是迭代器就产生了。