lua函数深入了解

    函数是一种“第一类值”,它们具有特定的词法域。

    “第一类值”表示在lua中函数域其他传统类型的值句用相同的权利。函数可以存储到变量中(无论是全局变量还是局部变量)或table中,可以作为实参传递给其他函数,也可以作为其他函数的返回值。

    “词法域”是值一个函数可以嵌套在另一个函数中,内部的函数可以访问外部函数中的变量。

    函数与所有其他值一样都是匿名的,即他们都没有名称。当讨论一个函数名,实际上是在讨论一个持有某函数的变量。这与其他变量持有各种值一个道理,可以以多种方式来操作这些变量。如下例:

local a = {p = print}
a.p("hello world")
print = math.sin 
a.p(print(1))
sin = a.p
sin(10,20)

    输出为:

hello world
0.8414709848079
10	20

    我们经常这样定义函数

 function foo(x) return 2 * x end

    实际上,这只是一种“语法糖”而已;上述代码只是下面代码的一种简化书写形式

foo = function (x) return 2 * x end

    实际上,一个函数定义实际就是一条语句(更准确地说是一条赋值语句),这条语句创建了一种类型为“函数”的值,并将这个值赋予一个变量。由于函数在Lua中就是一个普通的值,所以不仅可以将其存储在全局变量中,还可以存储在局部变量甚至table的字段中。

    关于函数的语法域,我们看一下下面的例子:    

function new()
	local i = 0
	return function()
		i = i+1
		return i
    end
end

local new1 = new()
print(new1())
print(new1())

    输出为:

1
2

    在上述代码中,有一个变量i,对于函数new来说,i是一个局部变量,但是对于匿名函数来说,当它访问这个i时,i既不是全局变量,也不是局部变量,对于我们来说,我们称这样的变量为一个“非局部的变量”。下面这段代码也是同样的道理:

function new(i)
	return function()
		i = i+1
		return i
    end
end

local new1 = new(10)
print(new1())
print(new1())

    输出:

11
12

    匿名函数访问了一个“非局部的变量”i,该变量用于保持一个计数器。乍一看,由于创建变量i的函数,也就是new已经返回,所以之后每次调用匿名函数时,i都应该是已经超出了作用范围。但是,Lua会以closure的概念来正确地处理这种情况。一个closure就是一个函数加上该函数所需访问的所有“非局部的变量”。如果再次调用newCounter,那么它会创建一个新的局部变量i,从而将得到一个新的closure。关于闭包,我们接下来会进行讨论。


转载于:https://my.oschina.net/u/815187/blog/484954

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值