美文网首页
五 函数(function)

五 函数(function)

作者: 愤愤的有痣青年 | 来源:发表于2020-12-04 14:05 被阅读0次

    函数的声明格式

    function add(a,b,c)
            return a+b+c
    end
    

    多返回值

    在lua中允许函数返回多个结果,返回方式形如return a,b,其中a,b参数不可用()括住,否则会报错.
    需要注意的是,lua会根据函数的被调用情况调整返回值的数量,如下情况

    function test()
        return 1,2
    end
    
    1. 当函数被作为一条单独语句调用时,其所有返回值都会被丢弃
    2. 函数被作为表达式(例如,加法的操作数)调用时,将只保留第一位返回值,例如 >test()+1 -->2

    只有当函数调用是一系列表达式中的最后一个表达式(或是唯一一个表达式)时,其所有的返回值才能被获取到.这里的一系列表达式在lua中表现为4种情况:

    1. 多重赋值.
    >a,b,c, d= test(), test() -->a=1,b=1, c=2  d=nil 这里的第一个test函数由于不是最后一个表达式,因此只有其第一个返回值被捕获并传递给了a参数
    
    1. 函数调用时传入的实参列表
    > print(test(),'end') --> 1, "end" 
    > print('start', test()) --> "start", 1,2
    
    1. 表构造器.可以用此方法将所有返回值存入单个变量中
    > t = {test()} --> t={1, 2}
    > t= {test(), test()} --> t={1,1,2}
    
    1. return 语句.形如return f()的语句会返回f返回的所有结果

    可变长函数参数

    lua中使用...表示可变长函数参数,例如

    function test(...)
         for _,v in pairs({...}) do
            print(v)
          end
    end
    

    获取可变长参数可以采用
    a,b=...的形式,其会将...中的前两位保存到a b变量中

    可变长参数和固定参数是可以一起使用的,但是固定参数必须在函数参数的前面, 例如

    function test(a,b,...)
    end
    

    要遍历...参数,也可以使用table.pack函数,该函数接收一个可变长参数,返回由该可变长参数组成的一个数组,并增加一个字段n,代表该数组的长度,例如

    function test(...)
        local arg = table.pack(...)
        print(arg.n)
        print(arg[1])
        print(arg[arg.n])
    end
    

    > test(1,2,3,4,5) --> 5 1 5

    遍历...参数还有一种方法,即使用select函数,该函数总是具有一个固定参数selector,以及数量可变的参数,如果selector是数值n,那么select函数返回地n个参数(包含第n个)后的所有参数.selector参数也可以是#,表示返回参数的总数.

    函数table.unpack

    table.unpack函数与table.pack相反,其功能为将一个列表解包为一个边长参数,例如
    a,b = table.unpack({1,2,3}) --> a=1,b=2

    函数的尾调用

    当一个函数的最后一个动作是调用另一个函数而没有在进行其他工作时,就形成了尾调用.例如:
    function f1() return f2() end
    当f1函数调用完f2函数后即不再进行其他的任何操作,这样当f2函数执行完成后,程序就不再需要返回最初的调用函数f1.因此在尾调用之后,程序也就不需要在调用栈中保存有关调用函数的任何信息.当f2函数返回时,程序的执行路径会直接回到调用f1函数的位置.
    这种在尾调用时不使用任何额外的栈空间,我们将这种实现称为尾调用消除

    但是对于如下的一些用法并不是尾调用

    • function f1() f2() end -- 此方式的函数,在f2运行完后,还需要在f1中丢弃f2函数的返回值,因此不属于尾调用

    • return 1+f2() -- 此方式在f2运行完成后,还需要对其返回值做运算操作,也不属于尾调用

    • return x or f2() -- 在f2调用完成后还需要做判断,不属于尾调用

    • return (f2()) -- 强制将 f2函数返回值变为一个参数,不属于尾调用

    lua语言中,只有形如return func(args)的调用才是尾调用,但对于args参数可以是任何复杂的表达式

    相关文章

      网友评论

          本文标题:五 函数(function)

          本文链接:https://www.haomeiwen.com/subject/swybwktx.html