每日一Lua(4)-深入函数

每日一Lua(4)-深入函数,第1张

概述1.函数是Lua中的第一值 在Lua中,函数能够像数字和字符串那样,存储在变量和table中,也能作为参数进行传递,也可以作为函数的返回值。 2.词法域 一个函数可以访问外部函数的变量。 3.匿名函数 函数与所有其他值一样都是匿名的,即他们都没有名称,我们可以把函数看成一个值。可以将它赋给某个变量。 foo=function ( x ) return 2*xendprint(foo(2))

1.函数是Lua中的第一值

在Lua中,函数能够像数字和字符串那样,存储在变量和table中,也能作为参数进行传递,也可以作为函数的返回值。

2.词法域

一个函数可以访问外部函数的变量。

3.匿名函数

函数与所有其他值一样都是匿名的,即他们都没有名称,我们可以把函数看成一个值。可以将它赋给某个变量。

foo=function ( x )	return 2*xendprint(foo(2))

4.函数作为参数传递

在table中有一个sort函数,接受一个table值和一和函数作为参数。例如:

classmate={	{name="Jack",grade="90"},{name="Rose",grade="80"},{name="Tomas",grade="88"},{name="Mary",grade="60"}}foo=function ()    for k,val in ipairs(classmate) do   		print(val.name.."-"..val.grade)	endendprint("Before sort:")foo()print("SortByname:")table.sort(classmate,function(a,b) return(a.name)>b.name end)foo()print("SortByGrade:")table.sort(classmate,b) return(a.grade)>b.grade end)foo()

运行结果:


这时候匿名函数就体现了很好的便捷性。

再看一个例子,函数求导。

导数的定义就是(f(x+d)-f(x))/d,其中d趋于无穷小。下面是lua实现。

function derivative( f,delta )	delta=delta or 1e-4	return function(x)			return(f(x+delta)-f(x))/delta		endend	c=derivative(math.sin)print(math.cos(10),c(10))


个人感觉有点乱--

5.闭合函数
若将一个函数写在另一个函数之内,那么这个位于内部的函数可以访问外部函数中的局部变量,这种特征称为“词法域”。

一个计数器的例子:

function newCounter()local i=0	return function()		i=i+1		return i		endendc1=newCounter()print(c1())print(c1())print(c1())


对于newCounter中的匿名函数,i为“非局部变量”,用于保持一个计数器,在匿名函数调用i的时候,看似已经超出了范围,实际上Lua会以closure的概念来正确的处理这种情况。这就是闭包。简单的讲,一个closure就是一个函数加上该函数所需方位的所有“非局部的变量”。如果再次调用newCounter,它就会创建一个新的局部变量i,从而得到一个新的closure。

接着上面的程序,执行下面的语句:

c2=newCounter()print(c2())print(c2())


c1和c2为一个函数所创建的两个不同的closure,他们个字拥有局部变量i的独立实例。


6.非全局函数

非全局函数指的是把函数当作一般的变量,如整数,字符串。将其存储在table字段中和局部变量中。例如:

lib={}lib.add=function(x,y) return x+y endlib.mul=function(x,y) return x-y endprint(lib.add(1,2))print(lib.mul(3,100))



还有一个递归调用的例子

--local fact=function(n)local function fact(n)if n==0 then return 1	else return n*fact(n-1)	endendprint(fact(100))



注释的那一行是报错的写法,因为在递归调用的时候发现fact没有定义,后者是正确的。


7.正确的尾调用

尾调用类似于goto的函数调用,当一个函数调用的是另一个函数的最后的一个动作时,该调用才算尾调用。

例如,f在调用完g之后就再也无其他事情可做。

function f(x) <some operation> return g(x) end

Lua中尾调用的机制就是在确定为尾调用之后,执行完尾调函数就不需要返回原函数了,程序也不需要保存任何关于该函数的栈信息,不耗费任何栈空间,在lua中称为尾调用消除。

尾调用的一个很大的应用就是有限状态机了,从这个状态跳到令一个状态,然后可以无穷跳,而不用考虑栈的溢出,是不是很棒!

总结

以上是内存溢出为你收集整理的每日一Lua(4)-深入函数全部内容,希望文章能够帮你解决每日一Lua(4)-深入函数所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1265496.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存