- 0X2C 表的遍历
- 这里简单说明一下迭代器是什么.如果看不懂可以跳过.
- 在Lua中ipairs和pairs函数都会返回三个返回值.
a,b,c=ipairs(list) print('list:',list) print('a,b,c',a,b,c)
- 第一个是一个函数,第二个是要遍历的表本身,第三个是遍历的起点.
- 其中的遍历起点一般是0(pairs是nil).如果不是0,则在遍历时就以这个索引为起点(遍历时不访问起点本身).
- 本质上Lua中表便利的语法应该这样写(为了明显我这里直接用list和0取代了b和c,如果a是由pairs返回的函数,则c的位置上应该是nil).
for i,v in a,list,0 do print(i,v) end
- 最后来说说a.这个函数接受两个参数:一个表和一个索引值.它也返回两个值,这两个值是表b中的一组键值对(索引和索引对应的值)例如:
i,v=a(b,c)
- 在Lua中ipairs和pairs函数都会返回三个返回值.
- 前边说的函数a的返回值其实是一个两次查表的过程.它接受的参数b是一张表,它内部还有一张表(通过闭包保存的,假设叫x).它返回的是:
return x[c],b[x[c]]
- 对于ipairs,x的长度等于#list.对于pairs,x的长度等于表的总元素个数.
- 把所有的要遍历的键值对的键按照系统内默认的顺序排好.按照如下方法生成x:
- 0作为索引时对应值为原来的表的第一个索引.(pairs需要用nil,这是函数内部进行了一次判断分情况给出了返回值.nil不能直接作为表的索引.)
- 第一个索引作为索引时对应值为原来的表的第二个索引.第二个索引对应第三个,第三个对应第四个以此类推.
- 最后一个索引作为索引时,对应值为nil.
- 引入x之后就能实现以下三点:
- 对于pairs来说把不连续的表整合成一张表.对于ipairs来说把不连续的键值对剔除.
- 返回值的同时能返回键(因为原来的键和值现在都成了值.)
- x[cc]会返回排在cc后边的那一个键.在把这个键代进去又能获得下一个.从而推动遍历.(0或者nil作为第一个cc的值.每次都更新cc=x[cc].直到x[cc]等于nil,则遍历结束.)
- ipairs和pairs这两个函数生成器封装了上述过程.
- 以上过程是根据ipairs和pairs的表现逆向猜测出来的.由于Lua虚拟机由C语言实现.所以一些机制的实现其实不应当用Lua的概念来解释.
- 这里补充说明一条.pairs遍历的表的索引看似是不用排序的.但是系统内部按照一定的规则把所有的非数字索引成员也排了序.pairs在遍历非数字索引成员的时候就按照这个系统内部的顺序遍历.在Lua中提供了函数next用来查看系统内部如何给键值对排序(哪怕索引是非数字值).尝试以下代码.
list={11,22,33,qq=44} next(list) next(list,1) next(list,2) next(list,3)
- 这里注意,next函数返回的值有两个.第一个是下一个索引,第二个是下一个索引对应的值.
- 更一般地说,for语句中,i后边只要有一个函数就可以(函数后边的项目会当作参数传递给这个函数).只不过如果函数没有闭包机制,很容易造成死循环.这里有一个简单的例程:
function creator()
local i=0
local f=function (x)
print('para',x)
i=i+1
if i<100 then
return i
else
return nil
end
end
return f
end
x=creator()
for i in x,'yes' do
print(i)
end
如果函数x有多个返回值,则在in之前可以用多个变量来接收.
在in后边,写的是x和'yes'
,这表示每次调用x的时候把'yes'
当作参数传递给它.这个参数也可以没有.
暂无