函数的定义:在Lua中,函数是一种对语句和表达式进行抽象的主要机制。
一、函数基本用法 在Lua中, 1、函数既可以完成某项特定的任务。(被视为一条语句) 2、也可以只做一些计算并返回结果。(被视为一句表达式)格式: function function_name( … )
— body
end
—- 等同于 function_name=function( … ) –body end
声明: function关键字声明函数。end 关键字定义函数体的结束位置。( … )参数列表用于值传递。调用: 以上无论哪种用法都需要将所有参数放到一对圆括号中,即使调用函数没有参数列表,也必须写出一对空括号。对于此规则只有一种特殊的例外情况:一个函数若只有一个参数,并且此参数是一个字面字符或table构造式,那么圆括号便是可有可无的。 二、多重赋值与多重返回值 定义:若实参多余形参,则舍弃多余的实参;若实参不足,则多余的形参初始化为nil。形式参数:由调用函数时的“实际参数”初始化的,用法与局部变量相似。如 在Lua中,会自动调整函数返回值的数量以适应不同的调用情况。 1、若函数调用作为一条单独的语句时,Lua会丢弃所有返回值。 2、若函数作为表达式中的一部分来调用时,Lua只会保留函数的第一个返回值。 3、只有当一个函数调用是一系列表达式中的最后一个元素(或仅有一个元素)时。才能获得函数的所有返回值。 特殊函数unpack:接受一个数组作为参数,并从下标1开始返回该数组的所有元素。unpack的一项重要用途体现在“泛型调用”机制中,泛型机制可以动态的以任何实参来调用任何函数。 三、变长参数 在Lua中函数还可以接受不同数量的实参。例如print函数,在调用时可以传入一个或多个实参。 函数的变长参数以 “…”三个点表示,函数如果要访问变长参数时,使用“{…}”表达式来访问,这样变长参数会以table表中的元素的形式存在,这就像访问一个table一样,访问所有变长参数。然而在某些特殊的情况下,变长参数中会有nil值,此时就需要使用select来访问变长参数。 调用select时必须传入一个固定的实参select(选择开关)和一系列变长参数。格式 1、select( index,… ) 返回从index下标开始一直到变长参数列表结尾的元素。 2、select( ‘#’,… ) 返回变长参数列表的长度 四、闭合函数 定义:若将一个函数写在另一个函数之内,那么这个位于内部的函数便可以访问外部函数中的局部变量,这项特征称之为“词法域”。外部函数中的局部变量在匿名函数内既不是全局变量,也不是局部变量,将其称之为“非全局变量”。 计数器的实现: 五、非全局的函数 只要将一个函数存储到一个局部变量中,就能得到一个“局部函数,也就是说只能在其作用域中使用。也可以在table中使用函数定义,即函数作为table中的元素存在。如: 当让Lua还有一种声明局部函数的方法: 六、正确的尾调用 尾调用的定义:当一个函数调用是另一个函数的最后一个动作时,该调用是一条“尾调用”。 function f( x ) return g( x ) end 尾调用的意义:当f函数调用完g函数后就再没有可执行的工作时,程序就不需要返回那个g所在的函数了。所以在尾调用之后程序也不需要保存任何关于该函数的栈信息了。当g返回时,执行控制权可以直接返回到调用f的那个点上。这种实现称为支持“尾调用消除”。 因此由于“尾调用”不会耗费栈空间,所以一个程序可以拥有无数嵌套的“尾调用”而不用担心造成栈溢出。必须明确确认尾调用: