在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
[写在前面:写这篇文章只是为了方便自己以后查阅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函数部分先写到这里,不足的以后再补充,希望大家多提意见,谢谢!) |
请发表评论