Lua迭代器 paris、ipairs

翻阅了Lua官方手册和Lua程序设计(第四版)

 

paris和iparis都是Lua语言的迭代器,用来遍历集合中的元素

二者在使用上有一些区分,以下是官方文档的定义

ipairs (t)

Returns three values (an iterator function, the table t, and 0) so that the construction

     for i,v in ipairs(t) do body end

will iterate over the key–value pairs (1,t[1]), (2,t[2]), ..., up to the first absent index.

 

pairs (t)

If has a metamethod , calls it with as argument and returns the first three results from the call. t__pairst

Otherwise, returns three values: the next function, the table , and nil, so that the construction t

     for k,v in pairs(t) do body end

will iterate over all key–value pairs of table . t

See function next for the caveats of modifying the table during its traversal.

 

英文水平较差,大致翻译下:

ipairs 返回三个值:迭代器函数、表、0 以便构造

将迭代键值对(1,t[1]), (2,t[2]])..直到第一个参数(索引)对应的值不存在

 

paris返回三个值:next函数、表、nil

可以遍历表的所有键值对

 

从上述翻译就可以看出iparis和paris的不同

对于iparis,从索引1开始遍历,一旦出现一个索引不存在的值,就停止遍历

1 a = {1,3,4,5}
2 for k, v in ipairs(a) do
3     print(k,v)
4 end
5 
6 b = {[1] = "a", [2] = "b", [4] = "c"} -- 不会输出 4 c  因为在 b[3] = nil 就停止迭代了
7 for k, v in ipairs(b) do
8     print(k,v)
9 end

输出

1       1
2       3
3       4
4       5
1       a
2       b

 

paris可以遍历所有键值对,将上述代码改为paris

a = {1,3,4,5}
for k, v in pairs(a) do
    print(k,v)
end

b = {[1] = "a", [2] = "b", [4] = "c"}
for k, v in pairs(b) do
    print(k,v)
end

输出

1       1
2       3
3       4
4       5
4       c
1       a
2       b

 

上述说明了iparis和paris的区别,但应该会对这两个函数的返回值无法理解

下面j介绍以下泛型for

 

泛型for在循环过程中保存了三个值,迭代函数、不可变状态(invariant state)、控制变量(control variable)

不可变状态是要迭代的对象
变量列表的第一个参数是控制变量
 

泛型for语法如下:

for var-list in exp-list do
    body
end

var-list是由一个变量或多个变量组成的列表

exp-list是一个或多个表达式组成的列表(通常只有一个表达式)


for 所做的一步是对in后的表达式求值,该表达式会返回上述所说的三个值
然后for使用不可变状态和控制变量为参数来条用迭代函数。
for将迭代函数的返回值赋给变量列表中的变量。如果第一个返回值为nil,那么循环终止,否则执行它的循环体并再次调用迭代函数
 
 
在执行遍历过程中 iparis 只被调用了一次,后续都是在使用iter函数进行迭代,这也就解释了为什么迭代器函数会有三个返回值
local function iter(t,i)
    i = i + 1
    local v = t[i]
    if v then return i, v end
end

function iparis(t)
    return iter, t, 0
end

 

pairs与iparis类型,区别只是迭代器函数是next

调用next(t,k), k是表t的一个键,该函数会以随机次序返回表中的下一个键及k所对应的值

第一次调用时k是nil,返回表中的第一个键值对。对所有元素遍历完后,函数next返回nil

 

 

 

posted @ 2020-11-13 16:13  世味  阅读(575)  评论(0编辑  收藏  举报