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

lua语言中的函数概念

2017-06-02 22:45 281 查看

1. 不同于C,lua中的函数是一种first-class-value,这意味着:

            lua中的函数可以视作一种"值"存储到变量或table中;

            可以作为其他函数的实参;

            可以作为其他函数中的返回值;

            可以嵌套在其他函数中被构造创建,而无需在设计阶段就定义好.

  

2. lua中的函数本身其实都是没有名字的,也就是说通常讨论的函数名(比如print),实际不过是持有某个函数的变量.

   所以,lua中函数的标准定义形式其实是:

            var = function (x) <body> end

   也就是说,一个函数定义其实就是一条赋值语句,这条语句首先是构造一种类型为"函数"的值,然后将这个值赋给一个变量

3. 跟其他大部分语言一样,lua遵循"词法域"(即静态作用域)的原则,又因为lua函数是一种first-class-value,所以才有了闭包(closure)的概念:

            一个闭包就是一个函数加上构造该函数时所需的所有"非局部的变量"(non-local variable)

   一个闭包的典型例子如下:

            function newCounter ()

                local i = 0

                return function ()  -- 匿名函数,也就是闭包

                    i = i + 1

                    return i

                end

            end

            c1 = newCounter()

            c2 = newCounter()

            print(c1)   -- 1

            print(c1)   -- 2

            print(c2)   -- 1

   这个例子中,变量i对于匿名函数来说,既不是全局变量,也不是局部变量,所以就被称为了"非局部的变量";

   调用函数newCounter的过程,其实就是创建一个闭包的过程;

   这里要注意一点,函数名不带括号赋值给一个变量,其实是表示共同持有某个函数,而函数名带括号赋值给一个变量,其实是表示首先调用该函数,然后将该函数的返回值赋值给变量;

   所以以上例子中,c1和c2是同一个函数所创建的两个独立的闭包,也就是说,它们各自拥有独立的i

4. lua函数中存在一种"尾调用"概念:

            当一个函数的最后一个动作是调用另外一个函数,并且包含了关键字"return",那么这条调用就是该函数的尾调用。

   利用这种"尾调用"现象,lua实现了"尾调用消除"机制,原理就是:

            调用函数时,会在内存中形成一个"调用记录",主要保存调用位置和内部变量信息,经过多次嵌套调用函数之后,内

            存中就会堆叠这些"调
4000
用记录",形成一个"调用栈"。由于"尾调用"是所在函数的最后一步操作,一旦开始执行"尾调

            用"的函数,外层函数的调用记录就不会再用到,所以就直接释放这个调用记录,然后再写入"尾调用"的函数的调用

            记录即可。

   这种"尾调用消除"机制的意义很明显,那就是如果所有嵌套的函数都符合"尾调用",那么真个嵌套调用的过程中,调用记录同时只会有一项,这就大大节省了内存空间。

   一个典型的应用例子就是"尾递归",调用以下函数时,传入任何数字都不会造成栈溢出:

            function foo (n)

                if n > 0 then

                    return foo (n - 1)

                end

            end

   递归非常耗费内存,因为每次执行递归函数,就要往内存中增加一条调用记录,所以很容易发生"栈溢出"错误。但对于"尾递归"来说,由于同一时刻只会存在一个调用记录,所以永远不

   会发生"栈溢出"问题。

  

           
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: