Lua中的generic for

Posted 大龄社畜的游戏开发之路

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Lua中的generic for相关的知识,希望对你有一定的参考价值。

Lua的generic for是一个很好用的语法糖,它为我们隐藏了迭代器背后的细节,使用起来非常简单:

local l = {123}
for k, v in ipairs(l) do
    print("k, v ", k, v)
end
local t = {["a"] = 1, ["b"] = 2, ["c"] = 3}
for k, v in pairs(t) do
   print("k, v ", k, v) 
end

那么ipairs,pairs这两个函数,背后究竟做了什么?我们要如何去自定义实现这类函数呢?

lua规定这类函数需要返回三个值:迭代器函数_f,不变量_s,以及控制变量_v。迭代器函数_f接收不变量_s和控制变量_v作为函数的参数。迭代器函数_f可以返回若干个参数,其中第一个参数会被用来当作下一轮的控制变量_v传给迭代器函数_f,直到_v为nil为止。用代码表示的话,可以写成如下的函数:

function my_generic_for(func, ...)
    local f, s, v = func(...)
    while true do
        local v1, v2 = f(s, v)
        v = v1
        if not v then
            break
        end
        print("k v", v1, v2)
    end
end

我们可以调用一下试试:

my_generic_for(ipairs, {1,2,3})
my_generic_for(pairs, {['a'] = 1,['b'] = 2, ['c'] = 3})

那么,接下来让我们尝试去实现一下ipairs。ipairs用于对lua的list,即连续的数组进行迭代,从数组下标1开始,到数组元素为nil结束。有了这些特征,我们可以写一个自己的ipairs了:

function iter(s, v)
    v = v + 1
    if s[v] then
        return v, s[v]
    else
        return nil
    end
end

function my_ipairs(t)
    local _s = t
    local _f = iter
    local _v = 0

    -- 迭代器,不变量,变量
    return _f, _s, _v
end

同样地,让我们来试试:

local l = {345}
for k, v in ipairs(l) do
    print("k, v ", k, v)
end

类似地,我们也可以实现自己的pairs函数。pairs用到的迭代器函数是next,可以直接拿来用:

function my_pairs(t)
    local _s = t
    local _f = next
    local _v = nil

    -- 迭代器,不变量,变量
    return _f, _s, _v
end

然后尝试:

local t = {["a"] = 1, ["b"] = 2, ["c"] = 3}
for k, v in my_pairs(t) do
   print("k, v ", k, v) 
end


以上是关于Lua中的generic for的主要内容,如果未能解决你的问题,请参考以下文章

for 循环是不是遍历 Lua 和 Love2d 中的空表?

lua中的泛型for用法: for i, v in talbe do....end

在Pandoc lua过滤器中连接字符串片段

Lua_isms

Lua代码简化问题(变量,for循环)

openresty开发系列16--lua中的控制结构if-else/repeat/for/while