• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    Lua中的for循环和迭代器的秘密探究

    上一篇我们介绍了,可以使用for循环来完成迭代器的调用,十分简洁。
    那么,具体这for循环做了什么呢?我当然没有去看源码,我只是看书而已。
    资料来源于《Lua程序设计》第二版,如果这本书的内容没有错的话,那么,本篇文章理论上也不会有错~

    1.返回两个值的迭代器

    pairs是能遍历table的key和value的,而我们之前写的dieDaiQi函数只能返回value。
    所以,我们要改改dieDaiQi函数,如下:

    复制代码 代码如下:

    function dieDaiQi(t)
        local i = 0;
        return function()
            i = i + 1; 
          
            if i > #t then
                return nil;
            end         
            return i, t[i];
        end
    end

    当然了,这不是一个安全的迭代器,我们假设table中没有nil值。
    至于为什么要有一个if i > #t的判断,待会会说到。
     
    使用如下方式调用迭代器:

    复制代码 代码如下:
       
        local t = {"fdsd", "445", "9999"};
        for k, v in dieDaiQi(t) do
            print(k .. "," .. v);
        end

    输出结果如下:

    复制代码 代码如下:

    [LUA-print] 1,fdsd
    [LUA-print] 2,445
    [LUA-print] 3,9999

    2.for .. in .. do的真面目

    【for k, v in dieDaiQi(t) do  end】这段代码实际上等价于以下代码:

    复制代码 代码如下:

        do
            local _f, _s, _var = dieDaiQi(t);
          
            while true do
                local k, v = _f(_s, _var);
                _var = k;
              
                if _var == nil then
                    break;
                end
              
                print(k .. "," .. v);
            end
        end

    是不是很复杂?其实它和我们之前第一次调用迭代器的代码很像,我们先删掉复杂的部分,代码变成如下:

    复制代码 代码如下:

        do
            local _f = dieDaiQi(t);
          
            while true do
                local k, v = _f();
              
                if k == nil then
                    break;
                end
              
                print(k .. "," .. v);
            end
        end

    试试运行这段代码,结果如下:

    复制代码 代码如下:

    [LUA-print] 1,fdsd
    [LUA-print] 2,445
    [LUA-print] 3,9999

    和直接使用for in循环是一样的结果。
     
    实际上,我说的这些都是废话,因为我们之前就已经说,for in循环就是用来简化迭代器的调用的,所以当然是一样的结果。

    3.迭代器函数、恒定状态、控制变量初值

    我们来看看for in真面目的第一句代码:local _f, _s, _var = dieDaiQi(t);
    三个返回值分别代表迭代器函数(_f)、恒定状态(_s)、控制变量初值(_var)。
     
    迭代器函数:就不用解释了,就是我们的dieDaiQi返回的闭合函数。
    恒定状态:其实就是一个变量,这个变量一直不变,所以称之为恒定。
    控制变量初值:和恒定相对于的,这是一个会不断改变的变量。
     
    因为我本人没有实际使用过这种特性,所以没法举出实际的例子,只能从理论上去解释。

    1.比如我们的dieDaiQi函数,它只有一个返回值,就是那个闭合函数,所以,_s和_var都是nil。

    2.接着调用local k, v = _f(_s, _var); 这实际上就是调用了闭合函数,并且将恒定值和变量值都作为参数传递进去。

    3.Lua的函数是很自由的,即使_f函数本身没有参数,也可以传参数进去,不会影响什么,所以,两个nil值传进去了,没有任何事情发生,就像是直接调用_f()一样。

    4.再下一句代码:_var = k;  这是把闭合函数(_f)的第一个返回值保存起来,因为每次调用闭合函数(_f)返回值都是下一个迭代值,所以_var每次都是不一样的值。

    5.如果_var的值为nil,则停止循环,结束迭代。
     
    因此,我们编写迭代器的时候,迭代结束的方式就是让第一个返回值为nil。
     
    那么,如果我们让dieDaiQi函数返回恒定状态和控制变量初值,又是什么样的情况呢?
    代码如下:

    复制代码 代码如下:

    function dieDaiQi(t)
        local i = 0;
        return function(s, var)
            i = i + 1; 
          
            if i > #t then
                return nil;
            end       
            print("恒定值=" .. s .. ", 变量值=" .. var)
            return i, t[i];
        end, 10, 0
    end

    留意一下,dieDaiQi函数现在会返回三个参数,后面的10和0分别就是恒定状态和控制变量初值。
    同时,闭合函数也多了两个参数:s和var。
     
    于是,我们再次用for循环遍历迭代器:

    复制代码 代码如下:

        for k, v in dieDaiQi(t) do
            print(k .. "," .. v);
        end

    输出结果如下:

    复制代码 代码如下:

    [LUA-print] 恒定值=10, 变量值=0
    [LUA-print] 1,fdsd
    [LUA-print] 恒定值=10, 变量值=1
    [LUA-print] 2,445
    [LUA-print] 恒定值=10, 变量值=2
    [LUA-print] 3,9999

    恒定值自然是一直不变的,而变量值在每一次调用了闭合函数之后,就会赋值为k的值,所以变量值一直按着table的key值在变化。

    可能一时有点混乱,不过,只要对照着for .. in .. do .. end对应的实现代码,就很好理解了。

    4.结束

    终于写完了,我快撑不住了,一晚上写两篇文章,可够折腾的。

    现在眼睛都是花的…我不知道我还能坚持多少个晚上…

    幸好学习的内容会越来越难,这样我就没法一个晚上就理解透彻,也就没法每晚写一篇教程了~

    太好了,呵呵。(小若:想偷懒就偷懒吧,说这么多做什么)

    您可能感兴趣的文章:
    • Lua编程示例(三):稀疏表、双端队列、格式化输出、表和循环表的格式化输出
    • Lua编程中使用嵌套循环的使用教程
    • Lua中的repeat...until循环语句使用教程
    • 详解Lua中repeat...until循环语句的使用方法
    • Lua中for循环语句的使用教程
    • 详解Lua中的while循环语句的使用
    • Lua中数字for循环实例
    • Lua中变相实现continue跳出循环
    • Lua中三种循环语句的使用讲解
    上一篇:Lua中的迭代器浅析
    下一篇:Lua的迭代器使用中应该避免的问题和技巧
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    Lua中的for循环和迭代器的秘密探究 Lua,中的,for,循环,和,迭代,