Lua中的函数(function)、可变参数、局部函数、尾递归优化等实例讲解
来源:互联网 发布:协议软件是什么 编辑:程序博客网 时间:2024/06/06 08:49
这篇文章主要介绍了Lua中的函数(function)、可变参数、局部函数、尾递归优化等实例讲解,需要的朋友可以参考下
一、函数
在Lua中,函数是作为"第一类值"(First-Class Value),这表示函数可以存储在变量中,可以通过参数传递给其他函数,或者作为函数的返回值(类比C/C++中的函数指针),这种特性使Lua具有极大的灵活性。
Lua对函数式编程提供了良好的支持,可以支持嵌套函数。
另外,Lua既可以调用Lua编写的函数,还可以调用C语言编写的函数(Lua所有的标准库都是C语言写的)。
定义一个函数
function hello()print('hello')end
hello函数不接收参数,调用:hello(),虽然hello不接收参数,但是还可以可以传入参数:hello(32)
另外如果只传递一个参数可以简化成functionname arg的调用形式(注意数值不行)
> hello '3'hello> hello {}hello> hello 3stdin:1: syntax error near '3'
另外对变量名也不适用
> a = 21> print astdin:1: syntax error near 'a'
另外,Lua函数不支持参数默认值,可以使用or非常方便的解决(类似Javascript)
> function f(n)>> n = n or 0>> print(n)>> end> f()0> f(1)1
Lua支持返回多个值,形式上非常类似Python:
> function f()>> return 1,2,3>> end> a,b,c = f()> print(a .. b .. c)123
函数调用的返回值可以用于table:
> t = {f()}> print(t[1], t[2], t[3])1 2 3
可见,f()返回的三个值分别称为table的3个元素,但是情况并不总是如此:
> t = {f(), 4}> print(t[1], t[2], t[3])1 4 nil
这次,f()返回的1,2,3只有1称为table的元素;
> t = {f(), f()}> print(t[1], t[2], t[3], t[4], t[5])1 1 2 3 nil
总之:只有最后一项会完整的使用所有返回值(假如是函数调用)。
对于无返回值的函数,可以使用(f())的形式强行返回一个值(nil)
> function g()>> end> print(g()) > print((g()))nil
实际上,(f())形式的调用返回一个且只返回一个值
> print((f()))1> print(f())1 2 3
二、变长参数
Lua支持编程参数,使用简单(借助于table、多重赋值)
> function f(...)for k,v in ipairs({...}) doprint(k,v)endend> f(2,3,3)1 22 33 3
使用多重赋值的方式
> function sum3(...)>> a,b,c = ...>> a = a or 0>> b = b or 0>> c = c or 0>> return a + b +c>> end> =sum3(1,2,3,4)6> return sum3(1,2)3
通常在遍历变长参数的时候只需要使用{…},然而变长参数可能会包含一些nil;那么就可以用select函数来访问变长参数了:select('#', …)或者 select(n, …)
select('#', …)返回可变参数的长度,select(n,…)用于访问n到select('#',…)的参数
> =select('#', 1,2,3)3> return select('#', 1,2, nil,3)4> =select(3, 1,2, nil,3)nil 3> =select(2, 1,2, nil,3)2 nil 3
三、函数式编程
函数做一个First-Class Value可以赋值给变量,用后者进行调用
> a = function() print 'hello' end> a()hello> b = a> b()hello
匿名函数
> g = function() return function() print 'hello' end end> g()()hello
函数g返回一个匿名函数;
闭包是函数式编程的一种重要特性,Lua也支持
> g = function(a) return function() print('hello'.. a); a = a + 1 end end> f = g(3)> f()hello3> f()hello4
四、局部函数
局部函数可以理解为在当前作用域有效的函数,可以用local变量来引用一个函数:
> do>> local lf = function() print 'hello' end>> lf()>> endhello> lf()stdin:1: attempt to call global 'lf' (a nil value)stack traceback:stdin:1: in main chunk[C]: in ?
需要注意的是,对于递归函数的处理
> dolocal lf = function(n)if n <= 0 thenreturnendprint 'hello'n = n -1lf(n)endlf(3)endhellostdin:8: attempt to call global 'lf' (a nil value)stack traceback:stdin:8: in function 'lf'stdin:9: in main chunk[C]: in ?
而应该首先声明local lf, 在进行赋值
dolocal lf;lf = function(n)if n <= 0 thenreturnendprint 'hello'n = n -1lf(n)endlf(3)endhellohellohello
Lua支持一种local function(…) … end的定义形式:
> dolocal function lf(n)if n <= 0 thenreturnendprint 'hello'n = n -1lf(n)endlf(3)endhellohellohello> lf(3)stdin:1: attempt to call global 'lf' (a nil value)stack traceback:stdin:1: in main chunk[C]: in ?
五、尾调用
所谓尾调用,就是一个函数返回另一个函数的返回值:
function f()…return g()end
因为调用g()后,f()中不再执行任何代码,所以不需要保留f()的调用桟信息;Lua做了这样的优化,称为"尾调用消除",g()返回后,控制点直接返回到调用f()的地方。
这种优化对尾递归非常有益,通常递归意味着调用桟的不断增长,甚至可能造成堆栈溢出;而尾递归提供了优化条件,编译器可以优化掉调用桟。
下面的递归函数没有使用尾递归,而参数为大数时,堆栈溢出:
> function f(n)>> if n <= 0 then>> return 0>> end>> a = f(n-1)>> return n * a>> end> f(10000000000)stdin:5: stack overflowstack traceback:stdin:5: in function 'f'stdin:5: in function 'f'stdin:5: in function 'f'stdin:5: in function 'f'stdin:5: in function 'f'stdin:5: in function 'f'stdin:5: in function 'f'stdin:5: in function 'f'stdin:5: in function 'f'stdin:5: in function 'f'...stdin:5: in function 'f'stdin:5: in function 'f'stdin:5: in function 'f'stdin:5: in function 'f'stdin:5: in function 'f'stdin:5: in function 'f'stdin:5: in function 'f'stdin:5: in function 'f'stdin:5: in function 'f'stdin:1: in main chunk[C]: in ?
优化为尾递归
function f(n, now)if n <= 0 thenreturn nowend return f(n-1, now*n)endf(10000000000, 1)
0 0
- Lua中的函数(function)、可变参数、局部函数、尾递归优化等实例讲解
- Lua function函数,可变参数, 局部函数,尾递归优化
- lua function 可变参数
- lua中的递归函数
- 将参数字符串中的字符反向排列(递归实现),可变参数列表函数实现
- lua中的handler和function()作为函数参数的不同
- 可变参数函数初探 Variable Paramenter Function
- 可变参数函数例子(variable parameter function)
- LUA函数可变参数数据获取
- 根据printf函数来讲解可变参数
- python中的函数可变参数
- 自学python(4)函数概述,参数,可变参数,关键字参数,组合参数,递归函数
- 可变参数 va_start/va_end等函数
- 可变参数函数的原理与实例
- Lua函数中的变长参数
- Python(8)函数之普通参数、参数默认值、可变参数、关键字参数、命名关键字参数及递归函数
- Python入门(三)——函数,参数,参数默认值,可变参数,关键字参数,组合参数,递归函数
- 可变参数函数(摘抄)
- 面试资料
- 图片viewpage动态添加小圆点
- 连接和运行时库文件搜索路径的设置
- 一道值得深思的面试题:写一个函数,返回一个数组中所有元素被第一个元素除的结果。
- IOS面试题
- Lua中的函数(function)、可变参数、局部函数、尾递归优化等实例讲解
- Ubuntu 1404下安装ARToolKit及GStreamer
- Objective-c NSData转NSString后为nil 的解决办法
- Scala 基础入门教程
- Java并发编程:并发容器之ConcurrentHashMap
- android 资源(开源项目、library,框架{完善中})
- 【LeetCode-63】Unique Paths II
- TCP协议疑难杂症全景解析
- [UE4]逻辑状态机组件