闲扯LUA之三

·070函数作为Lua的第一类值,像string和number类型的变量一样也可以有全局函数和局部函数之分。局部函数包括作为table的域的函数(如math.sin和os.time等)和使存放在局部变量中的函数(如local add = function(x, y) return x + y end)

·071作为table的域的函数可按如下几种方式创建:

1)

     lib = {}

     lib.add = function(x, y) return x + y end

     lib.minu = function(x, y) return x - y end

2)

     lib = {add = function(x, y) return x + y end, minu = function(x, y) return x - y end}

3)

     lib = {}

     function lib.add(x, y) return x + y end

     function lib.minu(x, y) return x - y end

--这是第一种方式的另一种语法描述。

·072对于存放在局部变量中的函数(即局部函数),它只在其chunk内可见。因此若你在Shell中按如下方式定义局部函数:local add(x, y) return x + y end。结果是再也无法使用它了,因为在Shell中,一行代码就是一个chunk(除非这行代码被包含在了控制语句或do...end中了)。

·073你可以在一个Lua脚本中按如下形式书写多个局部函数并相互调用,因为一个Lua脚本被看做是一个chunk,这样局部函数在整个脚本中都是可见的:

--Script name: test.lua

local add = function(x, y)

     return x + y

end

local function show()

     print(add(1, 1999)) --局部函数add在这里是可见的

end


local minu --先声明一个局部变量

minu = function(x, y) --将函数存放在此局部变量中即得到局部函数

     return x - y

end


·074在073的test.lua中使用三种方式创建了局部函数,但需要注意的是 如果这个局部函数是一个递归函数,则只能采用先声明再定义的方式 。例如:

local function fact(n)

     if n == 0 then

          return 1

     else

          return n * fact(n - 1)

     end

end

     由于在以上的代码中递归函数fact为采用先声明后定义的方式,Lua解释器就不会知道fact是一个局部函数,因此它会查找全局函数fact,从而导致错误。正确的代码如下:

local fact

function fact(n)

     if n == 0 then

          return 1

     else

          return n * fact(n - 1)

     end

end

·075当函数的最后一个动作是调用另一个函数时,我们称这种调用是尾调用。例如:

function creat_all()

     --实现代码

     return clean() --最后一个动作仅仅是调用了clean函数

end

尾调用有点像在函数的最后使用了C中的goto语句。

·076尾调用的好处是当被调用的函数结束时,程序不需要返回调用者中。因此程序就不需在栈中保存调用者的任何信息(用于返回调用者处的信息),即不适用额外的栈内存。这意味着递归的层次可以无限深而不导致栈内存溢出。例如:

function fun(n)

     if n > 0 then

          return fun(n - 1)

     end

end

此示例中,无论n为何值均不会导致栈内存溢出。

·077判断一下情形是否为尾调用:

a)

function fun()

     g(x)

     return

end

b)

function fun()

     return g(x) + 1

end

c)

function fun()

     return x and g(x)

end

d)

function fun()

     return (g(x))

end

e)

function fun()

     return lib.add(math.sin(0.5) + 2 ^ 3 - 12)

end

答案:只有e是正确的尾调用。
      a)fun在调用g后需要丢弃g(x)的值返回。
      b)调用完g(x)后,需要计算g(x) + 1的值,然后总fun函数返回。
      c)类似b)需要做逻辑运算。
      d)需要将g(x)的结果进行调整(只保留一个值)。
      e)在调用add函数前,Lua会首先计算出add括号中实参的值,调用结束后没有其它运算,不会返回fun函数。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值