• 【笨木头Lua专栏】基础补充05:迭代器番外篇


    关于迭代器的内容, 另一点点,只是已经无关紧要了。应该算是一种扩展吧。就一起来开开眼界好了~

    笨木头花心贡献。哈?花心?不。是用心~

    转载请注明,原文地址: http://www.benmutou.com/archives/1721

    文章来源:笨木头与游戏开发

     

     

    1.避免创建闭合函数

    我们之前一直在说的迭代器。都是要创建闭合函数。但,大家有没有想过,有了恒定状态和控制变量之后。是不是就不须要闭合函数了?

    先来回想一下之前的迭代器函数:

    1. function dieDaiQi(t)
    2.     local i = 0;
    3.     return function(s, var)
    4.         i = i + 1;  
    5.        
    6.         if i > #t then
    7.             return nil;
    8.         end        
    9.         return i, t[i];
    10.     end, 10, 0
    11. end

    这是最后一次介绍的dieDaiQi函数,此时已经拥有了恒定状态和控制变量了。

    不认为那个local i变量非常碍事吗?(小若:不认为)

    仅仅要把它去掉,那就不存在闭合函数了。

     

    我们把dieDaiQi函数改成这样子:

    1. function dieDaiQi(t)
    2.     return function(s, var)
    3.         var = var + 1;
    4.         if var > #s then
    5.             return nil;
    6.         end        
    7.         return var, s[var];
    8.     end, t, 0
    9. end

    我们把恒定状态改为t。控制变量初值仍然是0。

    调用dieDaiQi函数后。返回一个新的函数,这个函数已经不属于闭合函数了。

    于是。依照上一篇内容的介绍(不记得的就回头看看吧),每次调用函数时,參数s就是我们须要的table,參数var从0開始,取代了local i变量。

     

    怎么样?略微认为恒定状态和控制变量有点用处了吧?

     

    2.利用恒定状态创造很多其它变量

    刚刚所说的方法,是挺好的。但是。可以改变的变量仅仅有一个。假设这迭代器须要非常多变量呢?

    除了使用闭合函数之外。另一个办法——将永恒变为善变。

     

    我们继续改动dieDaiQi函数

    1. function dieDaiQi(t)
    2.     return function(s, var)
    3.         var = var + 1;
    4.         if var > #s.list then
    5.             return nil;
    6.         end        
    7.         s.money = s.money * s.money;
    8.         print("呵呵,钱。对我来说,就是一个数字而已:" .. s.money);
    9.         return var, s.list[var];
    10.     end, {list = t, money = 10}, 0
    11. end

    留意一下,如今返回的恒定状态是一个table({list = t, money = 10})。

    这个table在迭代过程中依然是恒定不变的。但。它里面的内容可就不一定了。

    试试调用这个迭代器吧:

    1.     local t = {"fdsd", "445", "9999"};
    2.    
    3.     for k, v in dieDaiQi(t) do
    4.         print("k=" .. k .. ", v=" .. v);
    5.     end

    输出结果例如以下:

    [LUA-print] 呵呵,钱,对我来说,就是一个数字而已:100
    [LUA-print] k=1, v=fdsd
    [LUA-print] 呵呵,钱,对我来说。就是一个数字而已:10000
    [LUA-print] k=2, v=445
    [LUA-print] 呵呵。钱,对我来说。就是一个数字而已:100000000
    [LUA-print] k=3, v=9999

     

    怎么样?尽管每次迭代都是同一个table,但table的内容但是随时在变的。

    就像某些人吖,嘴上说永远,行动却随时变。

    (小若:是说你自己吗?)

     

    3.不须要for循环的迭代器

    如今调用迭代器都是要用到for循环的,事实上,在非常久非常久曾经…有一个…(小若:停!

    我不是来听故事的)

    好吧,事实上,在曾经,迭代器是不使用for语句的。

     

    我们来模拟一下曾经的做法:

    1. function dieDaiQiHistory(t, func)
    2.     for i = 1, #t, 1 do
    3.         func(i, t[i]);
    4.     end
    5. end

    (小若:我噗。为什么一開始不这么做?这样多简单啊喂!

    咳咳。我们试试调用这个迭代器:

    1.     local t = {"fdsd", "445", "9999"};
    2.     dieDaiQiHistory(t, function(k, v)
    3.         print("k=" .. k .. ", v=" .. v);
    4.     end);

    于是,在调用迭代器的时候,我们不须要使用for循环(尽管迭代器里面还是使用了)。

    并且须要传递一个函数作为參数。用于回调。获得迭代的值。

     

    因为我没有大量地使用者两种形式的迭代器,所以也没法去对照他们。

    书上的作者是倾向于使用“现代”的迭代器。

     

    并且我也发现,部分Lua的库函数。也是使用了这样的形式的迭代。或许是历史原因。又或许是这样的形式有其特有的使用场合。

     

    4.结束

    好了,关于迭代器,已经结束了。

    感觉还不错,这是我第三遍翻这本书的前面章节了吧?果然还是得写写文章,才干理解地更透彻。印象也比較深刻。

    越到后面就越难坚持了,加油吧…

    (小若:所以说啊!为什么最后又用了省略号啊!用感叹号才显得比較有干劲啊…)

  • 相关阅读:
    转:选择学习“下一个”程序语言
    再谈 Web 字体的现状与未来
    堪称2008年最漂亮的50组图标(上)
    堪称2008年最漂亮的50组图标(下)
    回帖整理: 互联网的未来, 我们的未来, 算一个预告吧, 有空我会把这些观点一一展开
    [回帖整理]创业建议
    也论PageController/FrontController与MVC
    [回帖整理] 创业难
    是否非要用interface关键字来实现接口?
    又论社区风气, 与程序员是干嘛地的.
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/5383011.html
Copyright © 2020-2023  润新知