Lua学习笔记之函数
1、 函数的作用
函数主要完成指定的任务,这样的情况下函数作为调用语句使用,函数可以计算并返回值,这样的情况下函数作为赋值语句的表达式使用。
语法:
funcationfunc_name(arguments-list)
Statements-list
end
调用函数的时候,如果参数列表为空,必须使用()表示是函数调用。
Print(8*9,9/8)
a = math.sin(3) +math.cos(10)
print(os.date())
上述规则有一个例外,当函数只有一个参数并且这个参数是字符串或者表构造的时候,()是可选的:
print “hello world” <--> print(“hello world”)
dofile ‘a.lua’ <-->dofile(‘a.lua’)
lua函数实参和形参的匹配与赋值语句类似,多余部分被忽略,缺少部分用nil补足.
2、 返回多个结果值
Lua函数可以返回多个结果值,比如strng.find,其返回匹配串“开始和结束的下标”(如果不存在匹配串返回nil)
s,e = string.find(“hello lua users”,”lua”)
print(s,e) -->7 9
lua函数中,在return后列出要返回的值得到列表即可返回多值,如:
function maximum(a)
local mi = 1
local m = a[mi]
for i,val inipairs(a) do
ifval >m then
mi = i
m = val
end
return m,mi
end
print(maxmun({8,10,23,12,5})) -->23 3
3、 可变参数
Lua函数可以接受可变数目的参数,和C语言类似在函数参数列表中使用三点(…)表示函数有可变的参数。Lua将函数的参数放在一个叫arg的表中,除了参数以外,arg表还有一个域n表示参数的个数。
4、 命名参数
Lua的函数参数是和位置相关的,调用时实参会按照顺序依次传递给形参。有时候用名字指定参数是很有用的,比如rename函数用来给一个文件重命名,有时候我们记不起命名前后两个参数的顺序:
rename(old = “temp.lua”,new = “temp1.lua”)
上面的代码是无效,lua可以通过将所有的参数放在一个表中,把表作为函数的唯一参数来实现上面这段伪代码的功能,因为lua语法支持函数调用时实参可以是表的构造。
Rename{old = “temp.lua”,new = “temp1.lua”}
根据这个想法我们重定义了rename:
functionrename(arg)
returnos.rename(arg.old,arg.new)
end
5、 闭包
当一个函数内部嵌套另一个函数定义时,内部的函数体可以访问外部的函数的局部变量,这个特种我们称为词法定界。虽然这个看起来很清楚,事实并非如此:
假如有一个学生姓名的列表和学生名和成绩对用的表:现在根据学习生的成绩从高到低对学生进行排序,可以这样做:
Names = {“peter”,”paul”,”mary”}
Grades = {mary =10,paul = 7,peter = 8}
Table.sort(Names,function(n1,n2))
ReturnGrades[n1]>Grades[n2]
end)
创建一个函数实现此功能
function sortbygrade (Names,Grades)
table.sort(Names,function(n1,n2))
returnGrades[n1]>Grades[n2]
end)
end
例子中包含在sortbygrade函数内部的sort中的匿名函数可以访问sortbygrade的参数Grades,在匿名函数内部Grades不是全局变量也不是局部变量,我们称为外部的局部变量。
看如下代码:
functionnewCounter()
locali = 0
returnfunction() --匿名函数
i = i+1 --外部的局部变量
return i
end
end
c1 = newCounter()
print(c1()) --> 1
print(c1()) --> 2
匿名函数使用外部的局部变量保存它的计数,当我们调用匿名函数的时候i已经超出了作用范围,因为创建i的函数newCounter已经返回了,然后Lua用闭包的思想正确的处理了这样的情况。简单说闭包是一个函数加上它可以正确访问外部的局部变量。如果我们再次调用newCounter,将创建一个新的局部变量i,因此我们得到一个作用在新的变量i上的新闭包。
技术上说闭包指值而不是函数,函数仅仅是闭包的一个原形声明。