Lua中的generic for

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

local l = {1, 2, 3}
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})

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-epOSbQco-1614495917272)(F:\Learning\blogs\Lua中的generic for1.png)]

那么,接下来让我们尝试去实现一下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 = {3, 4, 5}
for k, v in ipairs(l) do
    print("k, v ", k, v)
end

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q4f3UQe3-1614495917274)(F:\Learning\blogs\Lua中的generic for2.png)]

类似地,我们也可以实现自己的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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OXbRuQ7o-1614495917276)(F:\Learning\blogs\Lua中的generic for3.png)]

如果你觉得我的文章有帮助,欢迎关注我的微信公众号(大龄社畜的游戏开发之路-

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BvlTlhfk-1614495917279)(F:\Learning\blogs\qrcode_for_gh_16d0016744ab_258.jpg)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值