简介lua中关于for
lua中for语句有两种形式:数值型和泛型
1.数字型
数值型语法如下:
for var = e1,e2,e3 do Dosomething() end
这其中var是局部变量,作用域只在这个for循环当中,e1是var的初始值,当var< e2时循环执行,e3是var增加的步长。
其中e3为nil时,默认为1。
2.泛型
提到泛型for,就得顺带提及闭包。闭包简单的来说,就是一个函数包含局部变量,且返回值是函数的函数。这里不展开讲述,想更多了解闭包可以自行百度一下,有很多相关文章。
这里多提一嘴,闭包并不是lua特有的性质,其实所有的编程语言,只要支持函数持有外部局部变量的引用时,局部变量内存空间不被释放,均可以实现闭包。例如c#,一个函数的返回值是委托的形式,也可以实现闭包。
回到for本身上来,泛型for其实其语法构成如下:
for var1,var2 in func,table,var do DoSomething() end
从语法上可以看出来,五个参数 var1,var2,func,table,var被关键字in分割开来。在关键字in后面,func是迭代函数,而table和var分别不可变状态和控制变量的初始值,这两个变量会作为func的参数去执行。而in前面两个参数,其实是func这个迭代函数的两个返回值(ps:只是这里举例有俩参数,其实具体多少个看func的返回值)。并且var1会当做func的第二个参数传入,继续执行func,直到func返回nil。
以上这段话翻译为代码如下:
local _f,_t,_var = func,table,var while true do local var1,var2 = _f(_t,_var) _var = var1 if _var == nil then break end end
3.实例
理论讲完了,这里举一两个例子补充说明一下。
例如for循环中经常所使用的ipair()这个函数,其实咱们就可以自己去实现。
local function iter(t,i) i = i + 1 local v = t[i] if v ~= nil then return i , v end end function ipairs(t) return iter,t,0 end
类似的pairs()函数的实现
function pairs(t) return next,t,nil end
不过也有人说,pairs函数比next会快上不少,我也看到过反对的帖子,也就没有在这种细节上去研究了,反正pairs肯定不会比next慢,所以大家还是尽量去使用pairs。
以上两个lua自带的迭代函数,其实都传入了控制变量的值,并没有形成自己的闭包,所以术语上应该称之为无状态迭代器。对应的如果,迭代函数是一个闭包,那么就不是无状态迭代器了。
这里最后举一个闭包实现的迭代器的例子,功能也是顺序遍历。
function iter(t) local i = 0 return function ipair(t) i = i + 1 return i , t[i] end end for k,v in iter(t) do print(k,v) end