函数
function fun(x, y)
....
return xxx
end
这个就是最简单的一个函数结构了,function申明,fun为函数名,x和y是参数,return返回值,最后以end结尾。需要注意的是,可以使用 ... 表示可变参数。
Lua中也有匿名函数的概念,就是没有函数名,当然别的地方也就调用不到。
function test()
return 1, 2
end
a, b, c = test()
print(a)
print(b)
print(c)
-- [[
返回的结果
1
2
nil
]]
当我们指定的变量数量大于函数返回的数量,那么多出来的就是nil。
关于Lua函数中多返回值的数量,在Lua会自动调整函数返回值的数量以适应不同的调用情况。
- 若函数调用作为一条单独的语句时,Lua会丢弃所有返回值。
- 若函数作为表达式中的一部分来调用时,Lua只会保留函数的第一个返回值。
- 只有当一个函数调用是一系列表达式中的最后一个元素(或仅有一个元素)时。才能获得函数的所有返回值。
unpack函数
unpack函数接受一个数组作为参数,并从下标1开始返回该数组的所有元素。unpack的一项重要用途体现在“泛型调用”机制中,泛型机制可以动态的以任何实参来调用任何函数。
function test(a, b, c)
print(a.." - "..b.." - "..c)
end
local tab = {"this", "is", "unpack"}
test("hello world", unpack(tab))
-- [[
返回的结果
hello world - thisis
]]
变长参数中的select函数
在接收变长参数时,我们可以使用
select('#', ...) -- 获得变长参数的长度
select(index, ...) -- 获得变长参数第index个参数的值
循环
循环总共有几种方式
for循环
数值型for
for var=exp1,exp2,exp3 do
<执行体>
end
-- 例子
for i=1,10 do
print(i)
end
exp1为初始值,exp2为终止值,exp3不存在的时候就默认步长为1。例子中遍历1-10,并以此输出。
泛型的for
for i, v in ipairs(a) do
print(i, v)
end
就是之前用到过的迭代器的形式
while
while(循环条件) do
循环体
end
-- 例子
i = 0
while( i <= 10) do
print(i)
i = i+1
end
repeat...until 循环
repeat
statements
until( condition )
其实就是别的语言里面的do..while循环
控制语句
break
使用了退出当前循环,基本上语言都这样的吧,就不说了。
goto
这个在很多语言里面被废弃的,在Lua里面还是存在的。可以跳转到需要的节点。
首先,我们需要使用 :: 节点名 :: 的形式来申明节点,然后再使用goto 节点名来完成跳转。
-- 这个例子来自菜鸟教程,申明下
local a = 1
::label:: print("--- goto label ---")
a = a+1
if a < 3 then
goto label -- a 小于 3 的时候跳转到节点 label
end
通过goto,我们可以实现别的语言continue的效果。
if..else
这个语句感觉没啥好说的。
运算符
这个没啥好讲的。


迭代器
我们通常使用迭代器来遍历table中的全部或者部分元素。而迭代器通常包括三个部分:
- 迭代函数,即怎么做迭代,迭代的标准是什么,最简单的那肯定就是直接指向下一个
- 状态常量,即保存当前和过去迭代的元素的状态。状态常量的有无,对应的就是多状态的迭代器和无状态的迭代器。
- 控制变量。
无状态迭代器
function iter (tab, index)
index = index + 1
local v = a[index]
if v == nil then
return index, v
end
end
这是一个最简单的遍历的迭代器,每次遍历tab的下一个元素,直到值为nil为止,这里面并没有保存元素状态的状态常量。
多状态迭代器
多状态的迭代器的实现方法有不少,最常见的实现方法就是使用闭包或者维护额外table来保存状态。
闭包
function elementIterator (collection)
local index = 0
local count = #collection
-- 闭包函数
return function ()
index = index + 1
if index <= count
then
-- 返回迭代器的当前元素
return collection[index]
end
end
end
table
这个的话其实就是额外维护这一个保存状态的table。
总的来说,多状态的迭代器相对无状态的迭代器,需要消耗更多的资源。如果真的需要多状态迭代器的话,可以选择闭包的方式,这样相对来说会更加的高效。
泛型for迭代器
Lua中,使用最多的迭代器应该就是使用for,它使用默认的迭代器进行迭代,是一种无状态迭代器方式,在使用中我们就用ipairs(tab)的方式来实现。而ipairs也可以通过我们刚才写的无状态迭代器进行实现。
function ipairs (tab)
return iter, tab, 0
end
模块与引用
项目肯定不是一个单独的文件,多文件的时候引用就显得必要。 我们定义一个文件modul.lua
xxxxxx
return modul
通过最后的return 文件名(模块名)的方式,使得该模块可以被别的模块所调用。
而别的模块再最开头可以使用
require("modul")
的方式可以对modul模块进行调用。
这个模块名可以是一个地址,如果在同一个目录下的话就可以直接模块名。