Lua 函数、闭包、尾调用总结
2014-08-22 15:54
399 查看
《lua 程序设计》在线阅读:http://book.luaer.cn/
完成指定的任务,这种情况下函数作为调用语句使用;
计算并返回值,这种情况下函数作为赋值语句的表达式使用。
调用函数的时候,如果参数列表为空,必须使用()表明是函数调用。
当函数只有一个参数并且这个参数是字符串或者表构造的时候,()可有可无,例如
多返回值的函数必须是作为表达式最后一个参数,否则只返回一个值
接收的话不足补nil,超出舍去,如
Lua将函数的可变参数放在一个叫arg的表中,除了参数以外,arg表中还有一个域n表示参数的个数。
先看如下代码:
我们称i为从c1的外部局部变量(external local variable)或者upvalue。
简单的说,闭包是一个函数以及它的upvalues
如果我们再次调用fn,将创建一个新的局部变量i:
当函数最后一个动作是调用另外一个函数时,我们称这种调用尾调用。
例如:
尾调用不需要使用栈空间,因此尾调用递归的层次可以无限制的。
例如下面调用不论n为何值不会导致栈溢出。
一些调用者函数调用其他函数后也没有做其他的事情但不属于尾调用。比如:
1.函数
函数有两种用途:完成指定的任务,这种情况下函数作为调用语句使用;
计算并返回值,这种情况下函数作为赋值语句的表达式使用。
1.1 语法
function func_name (arguments-list) statements-list; end;示例
function foo (x) return 2*x end foo = function (x) return 2*x end从上面我们可以看出lua函数定义实际上是一个赋值语句,将类型为function的变量赋给一个变量,需注意:
调用函数的时候,如果参数列表为空,必须使用()表明是函数调用。
当函数只有一个参数并且这个参数是字符串或者表构造的时候,()可有可无,例如
print "Hello World" <--> print("Hello World")
1.2 返回值
lua函数可以返回多个值function foo0 () end -- returns no results function foo1 () return 'a' end -- returns 1 result function foo2 () return 'a','b' end -- returns 2 results需注意返回多个值是:
多返回值的函数必须是作为表达式最后一个参数,否则只返回一个值
接收的话不足补nil,超出舍去,如
x,y = foo2() -- x='a', y='b' x,y = foo1(); -- x = 'a', y= nil x = foo2() -- x='a', 'b'舍去 x,y = foo2(), 20 -- x='a', y=20另外,括号可以强制返回一个值
print((foo2())) --> a
1.3 可变参数
可变参数用...来表示Lua将函数的可变参数放在一个叫arg的表中,除了参数以外,arg表中还有一个域n表示参数的个数。
function fn(name,nick,...) print(name,nick) -- 一撮毛 大帅锅 for i,v in ipairs(arg) do print(arg[i]) -- 1,2,3,4 end end fn("毛毛","大帅锅",1,2,3,4); -- name="毛毛",nick="大帅锅",arg={1,2,3,4; n = 4}
2.函数闭包
当一个函数内部嵌套另一个函数定义时,内部的函数体可以访问外部的函数的局部变量,这种特征我们称作词法定界。先看如下代码:
function fn() local i = 0 return function() -- 注意这里是返回函数的地址,不是执行 i = i + 1 return i end end c1 = fn() -- 接收函数返回的地址 print(c1()) --> 1 --c1()才表示执行 print(c1()) --> 2如上,调用c1()时,fn函数明显已经返回,lua闭包闭包思想正确处理这种情况:
我们称i为从c1的外部局部变量(external local variable)或者upvalue。
简单的说,闭包是一个函数以及它的upvalues
如果我们再次调用fn,将创建一个新的局部变量i:
c2 = fn() print(c2()) --> 1 print(c1()) --> 3 print(c2()) --> 2
3.函数尾调用
尾调用是一种类似在函数结尾的goto调用。当函数最后一个动作是调用另外一个函数时,我们称这种调用尾调用。
例如:
function f(x) return g(x) -- 类似于goto g(x)函数的地址 end
尾调用不需要使用栈空间,因此尾调用递归的层次可以无限制的。
例如下面调用不论n为何值不会导致栈溢出。
function foo (n) if n > 0 then return foo(n - 1) end end需要注意的是:必须明确什么是尾调用。
一些调用者函数调用其他函数后也没有做其他的事情但不属于尾调用。比如:
function f (x) g(x) return end上面这个例子中f在调用g后,不得不丢弃g地返回值,所以不是尾调用,同样的下面几个例子也不时尾调用:
return g(x) + 1 -- 还需+1 return x or g(x) -- 还需比较 return (g(x)) -- 还需调整为一个返回值
相关文章推荐
- Lua 函数、闭包、尾调用总结
- lua 函数调用1 -- 闭包详解和C调用
- lua 函数调用1 -- 闭包详解和C调用
- lua 函数调用1 -- 闭包详解和C调用
- lua 函数调用1 -- 闭包详解和C调用
- lua 函数调用 -- 闭包详解和C调用
- 函数调用方式总结
- 通过例子学习Lua(4)--函数的调用
- VC各类之间的调用函数总结
- [LUA学习笔记03]LUA函数和C函数的相互调用
- c++调用lua函数
- C/C++中调用LUA函数
- 函数调用方式总结
- 原来 JS 也支持跟 Lua 语意一样的内嵌函数的闭包概念
- 关于对js从服务器端取到的值进行函数调用的总结
- js调用cs中函数的方法 和 在cs中调用js函数的方法〔总结〕
- 函数调用规则总结
- 对几种函数调用约定的总结
- 原来 JS 也支持跟 Lua 语意一样的内嵌函数的闭包概念
- VC各类之间的调用函数总结