当前位置: 首页 > 编程笔记 >

Lua的迭代器使用中应该避免的问题和技巧

柴丰
2023-03-14
本文向大家介绍Lua的迭代器使用中应该避免的问题和技巧,包括了Lua的迭代器使用中应该避免的问题和技巧的使用技巧和注意事项,需要的朋友参考一下

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

1.避免创建闭合函数

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


function dieDaiQi(t)

    local i = 0;

    return function(s, var)

        i = i + 1;  

       

        if i > #t then

            return nil;

        end        

        return i, t[i];

    end, 10, 0

end

这是最后一次介绍的dieDaiQi函数,此时已经拥有了恒定状态和控制变量了。
不觉得那个local i变量很碍事吗?(小若:不觉得)
只要把它去掉,那就不存在闭合函数了。
 
我们把dieDaiQi函数改成这样子:


function dieDaiQi(t)

    return function(s, var)

        var = var + 1;

        if var > #s then

            return nil;

        end        

        return var, s[var];

    end, t, 0

end

我们把恒定状态改为t,控制变量初值仍然是0。
调用dieDaiQi函数后,返回一个新的函数,这个函数已经不属于闭合函数了。
于是,按照上一篇内容的介绍(不记得的就回头看看吧),每次调用函数时,参数s就是我们需要的table,参数var从0开始,代替了local i变量。
 
怎么样?稍微觉得恒定状态和控制变量有点用处了吧?

2.利用恒定状态创造更多变量

刚刚所说的方法,是挺好的,但是,能够改变的变量只有一个,如果这迭代器需要很多变量呢?

除了使用闭合函数之外,还有一个办法——将永恒变为善变。
 
我们继续修改dieDaiQi函数:


function dieDaiQi(t)

    return function(s, var)

        var = var + 1;

        if var > #s.list then

            return nil;

        end        

        s.money = s.money * s.money;

        print("呵呵,钱,对我来说,就是一个数字而已:" .. s.money);

        return var, s.list[var];

    end, {list = t, money = 10}, 0

end

留意一下,现在返回的恒定状态是一个table({list = t, money = 10})。
这个table在迭代过程中依旧是恒定不变的,但,它里面的内容可就不一定了。
试试调用这个迭代器吧:


    local t = {"fdsd", "445", "9999"};

   

    for k, v in dieDaiQi(t) do

        print("k=" .. k .. ", v=" .. v);

    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语句的。
 
我们来模拟一下以前的做法:


function dieDaiQiHistory(t, func)

    for i = 1, #t, 1 do

        func(i, t[i]);

    end

end

(小若:我噗,为什么一开始不这么做?这样多简单啊喂!)
咳咳,我们试试调用这个迭代器:


    local t = {"fdsd", "445", "9999"};

    dieDaiQiHistory(t, function(k, v)

        print("k=" .. k .. ", v=" .. v);

    end);

于是,在调用迭代器的时候,我们不需要使用for循环(虽然迭代器里面还是使用了)。
并且需要传递一个函数作为参数,用于回调,获得迭代的值。
 
由于我没有大量地使用者两种形式的迭代器,所以也没法去对比他们。
书上的作者是倾向于使用“现代”的迭代器。
 
而且我也发现,部分Lua的库函数,也是使用了这种形式的迭代,也许是历史原因,又也许是这种形式有其特有的使用场合。

4.结束

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

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

越到后面就越难坚持了,加油吧…
(小若:所以说啊!为什么最后又用了省略号啊!用感叹号才显得比较有干劲啊…)

 类似资料:
  • 问题内容: 我读到应该避免赞成和。我对弄乱Loop并没有信心,也没有完全理解Codex。 下面的代码是否使用?如果是,并且由于应该避免,那么您能建议一种不使用但仍然完成相同任务的方法吗? 此代码用于按随机或按价格对帖子进行排序。 。 使用此代码将链接A(随机)和链接B(价格)发布在我的菜单中。因此,网站的访问者只需单击链接即可对帖子进行排序。 问题答案: 我已经针对WPSE这个主题做了非常详细的解

  • 本文向大家介绍Lua中的迭代器浅析,包括了Lua中的迭代器浅析的使用技巧和注意事项,需要的朋友参考一下 今天学习的内容还蛮有意思的,让我兴奋了一下~ 1.迭代器 什么是迭代器?别傻了,我最讨厌的就是名词解释了,反正就是用来遍历集合的一种方式。 比如,我们最常用的pairs,如下代码:   这是一次遍历table的操作,然后打印出table的key值和value值。 输出结果如下: 2.自己写一个迭

  • 主要内容:泛型 for 迭代器,实例,无状态的迭代器,实例,实例,多状态的迭代器,实例迭代器(iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址。 在 Lua 中迭代器是一种支持指针类型的结构,它可以遍历集合的每一个元素。 泛型 for 迭代器 泛型 for 在自己内部保存迭代函数,实际上它保存三个值:迭代函数、状态常量、控制变量。 泛型 for 迭代器提供了集合的 key/value 对,语法格式如下: 上面代码中,

  • 迭代器(iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址 在Lua中迭代器是一种支持指针类型的结构,它可以遍历集合的每一个元素。 泛型 for 迭代器 泛型 for 在自己内部保存迭代函数,实际上它保存三个值:迭代函数、状态常量、控制变量。 泛型 for 迭代器提供了集合的 key/value 对,语法格式如下: for k, v

  • 问题内容: 有时是有用的,例如,如果我为网站上的所有链接(例如选择器)定义了通用样式,但是当我要覆盖某些规则时,可以有以下选择: 使用更具体(更长)的选择器 采用 哪种方法更好,可能有一些指导原则? 问题答案: 使用非常,非常谨慎- 它会覆盖刚才的一切,甚至是内联样式和混乱在低于显而易见的方式与样式规则“梯级”,让CSS的名字。它很容易使用不当,而且容易成倍增加,尤其是在滥用时。您可以轻松地得出一

  • 问题内容: 一次又一次,我看到Bash在Stack Overflow上使用了答案,而答案被猛烈抨击了,旨在使用这种“邪恶的”构造。为什么这么邪恶? 如果不能安全使用,我应该怎么用呢? 问题答案: 这个问题比眼前的问题还重要。我们将从显而易见的内容开始:具有执行“脏”数据的潜力。脏数据是指尚未重写为XYZ的任何数据;在我们的例子中,它是未格式化的任何字符串,以确保评估安全。 乍看之下,对数据进行消毒