[写在前面:写这篇文章只是为了方便自己以后查阅Lua的基础知识,并无深刻见解,完全参考《Lua程序设计(第二版)》]
一、函数基础
1.函数定义
(1)标准形式:f = function(<参数>) <函数体> end
(2)语法糖形式:function f(<参数>) <函数体> end
2.函数调用
(1)一般形式:函数名(<参数>),圆括号一般是必须的
(2)省略圆括号()的情况:函数只有一个参数,并且此参数为字面字符串(“”)(注:不是字符串变量)或table构造式({})
例如:print"Hello Lua"等价于print("Hello Lua"),f{x=10,y=20} 等价于f({x=10,y=20})
(3)实参数量:当实参数量与形参数量不一致时,采用“多余舍弃,不足则形参为nil”原则
3.多重返回值
(1)含义:一个函数返回多个结果(值),即在return r1,r2,r3...
(2)返回值情况
①不返回值:函数调用作为单独一条语句。例如:f()
②返回第一个值:函数调用作为表达式的一部分(与③对立),或将函数放入一对圆括号中(例如:(f()))。
③返回所有值(或尽可能多的值):函数调用是 一系列表达式 中的最后一个元素(或仅有一个元素),只要不是最后一个元素就最多返回一个值。
“一系列表达式”的4种形式:1.多重赋值,2.函数调用时传入的实参列表,3.table的构造式,4.return语句
(3)注意:return 语句后面的类容不需要圆括号,否则会出现不同行为而得不到想要的结果,return(f(x))也不会得到f(x)的返回值。
4.变长参数
(1)函数形式:f(<固定参数列表>,...),三个点(...)表示函数可接受不同数量的实参,固定参数列表一定要在变长参数前面。
(2)访问方式:当访问变长参数(...)时,仍要用到三个点(...),此时作为表达式来使用,表达式“...”的行为类似一个具有多重返回值的函数。
例如:多重赋值:local a,b,c = ...,table构造式:{...}作为table使用,遍历table即可访问参数
(3)select函数:①select("#",...):返回变长参数的总数,包括中间nil的个数,②select(n,...):返回第n个实参的值
5.具名实参
含义:指定参数的名称。即函数接受一个table作为参数,函数会调用table中指定的字段
6.常用函数
(1)unpack(array):接受一个数组作为参数,从下标1开始返回数组中的元素,包括中间为nil的元素。
二、深入函数
1.深层含义
(1)函数是“第一类值”:函数和其他传统类型的值具有相同的权利。例如:存储到变量或table,即赋值,作为实参传递给函数,作为其他函数的返回值。
(2)函数具有特定的“词法域”:一个函数可以嵌套在另一个函数中,内部函数可以访问(并保存,即closure)外部函数的变量。
(3)函数是“匿名的”:函数可以没有名称,一般情况下,讨论函数时实际上是讨论一个持有某函数的变量,函数变量和其他变量一样,可以有多种方式操作它。
(4)函数定义是一条语句:这条语句创建了一种类型为“函数”的值,并赋给一个变量。
2.闭合函数(closure)
(1)定义:closure = 函数f + 函数f所需访问的所有“非局部的变量”(即外部函数的变量)。如果没有变量,则closure = 函数f,即函数是一个特殊的closure。
(2)形式:function F(x) ... return function ...end end
(3)作用:可保存外部函数的变量的状态,是外部函数中的局部变量具有“全局变量”的功能
【闭合函数很强大,暂时不知道怎么去描述,以后再补充】
3.非全局的函数
(1)解释:(还没弄明白这个名字是怎么来的)
(2)Lua展开局部函数的“语法糖”形式定义:
local function f(<参数>) <函数体> end Lua将其展开为:
①local f
②f = function(<参数>) <函数体> end
(3)直接递归函数定义:不能使用“语法糖”形式,而要使用展开后的形式
(4)间接递归函数定义:要先向前声明函数(定义时别再用local修饰,不然相当于重新定义了一个新函数)
4.正确的尾调用
(1)尾调用的含义:当一个函数调用是另一个函数的最后一个动作时,该调用才算是一条“尾调用”。
(2)尾调用的形式:return <func>(<args>)。lua会在调用前对func及参数args求值,即他们可以是任意复杂的表达式
(3)判断标准:一个函数在调用完另一个函数之后是否就没有其他事情需要做了
(4)尾调用的优点:不会耗费栈空间。(尾调用之后程序不需要保存任何关于当前函数的栈信息了)
(5)尾调用的应用:直接和间接递归
(Lua函数部分先写到这里,不足的以后再补充,希望大家多提意见,谢谢!)