LUA各知识点举例及详解.docx
- 文档编号:24396777
- 上传时间:2023-05-27
- 格式:DOCX
- 页数:11
- 大小:21.36KB
LUA各知识点举例及详解.docx
《LUA各知识点举例及详解.docx》由会员分享,可在线阅读,更多相关《LUA各知识点举例及详解.docx(11页珍藏版)》请在冰豆网上搜索。
LUA各知识点举例及详解
5.11 遍历表的数组部分
ipairs()允许您在不使用数值for循环的情况下遍历一个表的数组部分。
一些编程人员倾向于使用ipairs()而不是数值for循环,因为这样更简洁:
1.> tbl = {"alpha", "beta", "gamma"}
2.> for idx,value in ipairs(tbl) do
3.>> print(idx, value)
4.>> end
5.1, alpha
6.2, beta
7.3, gamma
ipairs()函数接受一个表作为输入,返回遍历一个表的数组部分所需的所有信息,包括迭代器函数本身。
每一次迭代器函数的调用都返回一个元素的数值序号和这个元素本身。
这些变量可以按照您的期望任意命名,而且始终都在for循环的范围之内(即它们不能被这个范围之外的对象所访问)。
您可以通过在解释器里执行以下几个语句来更深入地了解ipairs()函数:
1.> print(ipairs(tbl))
2.function:
0x300980, table:
0x3072c0, 0
3.> print(tbl)
4.table:
0x3072c0
解释器会显示ipairs()所返回的一个迭代器函数、状态(在这里是您传递给它的表)和迭代器的初始值(0)。
这里没有什么深奥的东西,只是一组有用的函数。
5.12 遍历完整的表
另一个函数,pairs()允许您完整地遍历一个表,包括表的数组部分和散列表部分。
使用方法和ipairs()一样:
将表传入其中,并作为范型for循环的一部分来使用即可:
1.> tbl = {"alpha", "beta", ["one"] = "uno", ["two"] = "dos"}
2.> for key,value in pairs(tbl) do
3.>> print(key, value)
4.>> end
5.1, alpha
6.2, beta
7.one, uno
8.two, dos
使用pairs()函数遍历
在前面的样例中,pairs()函数好像是以元素添加的顺序来遍历的,但是这只是一个巧合。
在这个函数里遍历元素的顺序是不确定的,甚至是数值键也如此。
如果需要顺序地遍历表里的数值元素,就必须使用ipairs()函数,ipairs()可以保证顺序遍历。
pairs()函数的非顺序遍历由散列表的实现方式带来:
一个关联键/值(associatedkey/value)对的集合,没有内部顺序。
在使用pairs()函数的时候,您必须保证不添加元素。
这是因为pairs()调用了next()函数,在Lua5.1的参考手册中,对此函数有一些警告:
"在遍历中,如果您要对表中不存在的区域赋值,那么next()的行为是不确定的。
这样也许会修改已存在区域的值。
特别地,您也许会把已经赋值的区域清除掉。
"
这意味着若您在遍历的时候往表里添加元素,则next()也许没有反应,也可能更早地结束,或者会抛出一个错误。
在使用pairs()时,这一点必须牢记。
【责任编辑:
云霞 TEL:
(010)68476606】
5.13 表的清除
正如Lua5.1参考手册对next()函数所阐述的,您可以在遍历的过程里通过使用pairs()函数清除整个表。
下面的代码可以清除一个表里的所有元素:
1.for key,value in pairs(tbl) do
2. tbl[key] = nil
3.end
因为pairs()对于整个表的键都有作用,所以这是一个清除所有元素的捷径(如果您需要重新使用一个表)。
其他的迭代器
Lua里的许多其他函数都可以产生迭代器,这些迭代器也是非常有用的。
sring.gmatch()函数可以通过Lua模式匹配产生一个匹配string的迭代器。
在第6章里,您可以学习到更多关于这个函数和Lua模式匹配的信息,这里有一些样例:
for word in string.gmatch("These are some words", "%S+") do
print(word)
end
These
are
some
words
for char in string.gmatch("Hello!
", ".") do
print(char)
end
H
e
l
l
o
!
1.迭代器与Closure:
在Lua中,迭代器通常为函数,每调用一次函数,即返回集合中的“下一个”元素。
每个迭代器都需要在每次成功调用之间保持一些状态,这样才能知道它所在的位置和下一次遍历时的位置。
从这一点看,Lua中closure机制为此问题提供了语言上的保障,见如下示例:
1functionvalues(t)
2locali=0
3returnfunction()
4i=i+1
5returnt[i]
6end
7end
8t={10,20,30}
9it=values(t)
10whiletruedo
11localelement=it()
12ifelement==nilthen
13break
14end
15print(element)
16end
17--另外一种基于foreach的调用方式(泛型for)
18t2={15,25,35}
19forelementinvalues(t2)do
20print(element)
21end
22--输出结果为:
23--10
24--20
25--30
26--15
27--25
28--35
从上面的应用示例来看,相比于while方式,泛型for的方式提供了更清晰的实现逻辑。
因为Lua在其内部替我们保存了迭代器函数,并在每次迭代时调用该隐式的内部迭代器,直到迭代器返回nil时结束循环。
2.泛型for的语义:
上面示例中的迭代器有一个明显的缺点,即每次循环时都需要创建一个新的closure变量,否则第一次迭代成功后,再将该closure用于新的for循环时将会直接退出。
这里我们还是先详细的讲解一下Lua中泛型(for)的机制,之后再给出一个无状态迭代器的例子,以便于我们的理解。
如果我们的迭代器实现为无状态迭代器,那么就不必为每一次的泛型(for)都重新声明一个新的迭代器变量了。
泛型(for)的语法如下:
for
end
为了便于理解,由于我们在实际应用中
现在我们先给出表达式的原型和实例,如:
1functionipairs2(a)
2returniter,a,0
3end
该函数返回3个值,第一个为实际的迭代器函数变量,第二个是一个恒定对象,这里我们可以理解为待遍历的容器,第三个变量是在调用iter()函数时为其传入的初始值。
下面我们再看一下iter()函数的实现,如:
1localfunctioniter(a,i)
2i=i+1
3localv=a[i]
4ifvthen
5returni,v
6else
7returnnil,nil
8end
9end
在迭代器函数iter()中返回了两个值,分别对应于table的key和value,其中key(返回的i)如果为nil,泛型(for)将会认为本次迭代已经结束。
下面我们先看一下实际用例,如:
1functionipairs2(a)
2returniter,a,0
3end
4
5
6localfunctioniter(a,i)
7i=i+1
8localv=a[i]
9ifvthen
10returni,v
11else
12returnnil,nil
13end
14end
15
16a={"one","two","three"}
17fork,vinipairs2(a)do
18print(k,v)
19end
20--输出结果为:
21--1one
22--2two
23--3three
这个例子中的泛型(for)写法可以展开为下面的基于while循环的方式,如:
1localfunctioniter(a,i)
2i=i+1
3localv=a[i]
4ifvthen
5returni,v
6else
7returnnil,nil
8end
9end
10
11functionipairs2(a)
12returniter,a,0
13end
14
15a={"one","two","three"}
16do
17local_it,_s,_var=ipairs2(a)
18whiletruedo
19localvar_1,var_2=_it(_s,_var)
20_var=var_1
21if_var==nilthen--注意,这里只判断迭代器函数返回的第一个是否为nil。
22break
23end
24print(var_1,var_2)
25end
26end
27--输出结果同上。
3.无状态迭代器的例子:
这里的示例将实现遍历链表的迭代器。
1localfunctiongetnext(list,node)--迭代器函数。
2ifnotnodethen
3returnlist
4else
5returnnode.next
6end
7end
8
9functiontraverse(list)--泛型(for)的expression
10returngetnext,list,nil
11end
12
13--初始化链表中的数据。
14list=nil
15forlineinio.lines()do
16line={val=line,next=list}
17end
18
19--以泛型(for)的形式遍历链表。
20fornodeintraverse(list)do
21print(node.val)
22end
这里使用的技巧是将链表的头结点作为恒定状态(traverse返回的第二个值),而将当前节点作为控制变量。
第一次调用迭代器函数getnext()时,node为nil,因此函数返回list作为第一个结点。
在后续调用中node不再为nil了,所以迭代器返回node.next,直到返回链表尾部的nil结点,此时泛型(for)将判断出迭代器的遍历已经结束。
最后需要说明的是,traverse()函数和list变量可以反复的调用而无需再创建新的closure变量了。
这主要是因为迭代器函数(getnext)实现为无状态迭代器。
4.具有复杂状态的迭代器:
在上面介绍的迭代器实现中,迭代器需要保存许多状态,可是泛型(for)却只提供了恒定状态和控制变量用于状态的保存。
一个最简单的办法是使用closure。
当然我们还以将所有的信息封装到一个table中,并作为恒定状态对象传递给迭代器。
虽说恒定状态变量本身是恒定的,即在迭代过程中不会换成其它对象,但是该对象所包含的数据是否变化则完全取决于迭代器的实现。
就目前而言,由于table类型的恒定对象已经包含了所有迭代器依赖的信息,那么迭代器就完全可以忽略泛型(for)提供的第二个参数。
下面我们就给出一个这样的实例,见如下代码:
1localiterator
2functionallwords()
3localstate{line=io.read(),pos=1}
4returniterator,state
5end
6--iterator函数将是真正的迭代器
7functioniterator(state)
8whilestate.linedo
9locals,e=string.find(state.line,"%w+",state.pos)
10ifsthen
11state.pos=e+1
12returnstring.sub(state.line,s,e)
13else
14state.line=io.read()
15state.pos=1
16end
17end
18returnnil
19end
2014/10/13
Lua中的虚变量——"_"
分类:
Lua2013-11-0517:
57 395人阅读 评论
(1) 收藏 举报
lua虚变量
《ProgramminginLua》中有一段使用虚变量的代码,一些新手不太了解含义,这里讲解一下。
[html] viewplaincopy
1.一个典型的方法是使用虚变量(下划线)
2.local _, x = string.find(s, p)
3.-- now use 'x'
4....
Lua的函数可以具有多个返回值,比如下面的示例代码:
[html] viewplaincopy
1.print(string.find("example", "am")) --- 输出 3 4
string.find默认情况下返回两个值,即查找到的子串的起止下标,如果不存在匹配返回nil。
如果我们只想要string.find返回的第二个值,可以使用虚变量(即下划线)来存储丢弃不需要的数值。
[html] viewplaincopy
1.local _, s = string.find("example", "am")
2.print(s) ----- 输出 4
总结来说,用一些不太会用到的名字命名一个回收箱变量,然后把不需要的值都丢到里面去,这种做法被称作虚拟变量法。
ps:
"_"就是一个变量,打印下就应该理解了
[html] viewplaincopy
1.print(_) --输出3
学到现在发现一个有趣的事情,print可以这样用
(1)--1
print("1")--1
print(x)--nil
print("x")--x
5.2函数手册里面关于print的描述
print(···)
Receivesanynumberofargumentsandprintstheirvaluesto stdout,usingthe tostring functiontoconverteachargumenttoastring. print isnotintendedforformattedoutput,butonlyasaquickwaytoshowavalue,forinstancefordebugging.Forcompletecontrolovertheoutput,use string.format and io.write.
intendedfor用来…;目的在于
formattedadj.有格式的
instance例子,实例;情况;要求,建议;[法]诉讼手续
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- LUA 知识点 举例 详解