您的位置:首页 > 编程语言 > Lua

一、Lua函数详解

2016-01-28 14:19 495 查看
[写在前面:写这篇文章只是为了方便自己以后查阅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函数部分先写到这里,不足的以后再补充,希望大家多提意见,谢谢!)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: