Lua程序设计 函数 正确的尾调用

Lua中的“尾调用”就是一种类似于goto的函数调用,当一个函数调用是另一个函数的最后一个动作时,该调用才算是一条“尾调用”。【一个函数在调用完另一个函数之后,是否就无其他事情需要做了】

function f(x) return g(x) end
  也就是说,当f调用完g之后,f所代表的整个函数的调用才算执行完成也就无其他事情可做了。因此,这种情况中,程序就不需要返回那个“尾调用”所在的函数了。
所以在“尾调用”之后,程序也不需要保存任何关于该函数的栈信息了。
 当g返回时,执行控制权可以直接返回到调用f的那个点上。

Lua中进行“尾调用”时不耗费任何栈空间。所以一个程序可以拥有无数嵌套的“尾调用”。

function foo(n) 
  if n > 0 then return foo(n - 1) end
end
调用以上函数时,传入任何数字作为参数都不会造成栈溢出。

以下示例均不是“尾调用”

 return g(x) + 1 ----必须做一次加法。
 return x or g(x) ----必须调整为一个返回值。
return (g(x))   ----必须调整为一个返回值。
调用完一个函数之后就无需做其他事情了。

在Lua中,只有“return <func> (<args>)”这样的调用形式才算是一条“尾调用”,Lua会在调用前对<func>及其参数求值,所以它们可以是任意复杂的表达式。

return x[i].foo(x[j] + a*b, i+j)

Lua中“尾调用”的一大应用就是编写“状态机”。这种程序通常以一个函数来表示一个状态,改变状态就是goto到另一个特定的函数。

Lua程序设计 函数 正确的尾调用,布布扣,bubuko.com

时间: 2024-08-02 11:04:46

Lua程序设计 函数 正确的尾调用的相关文章

《lua程序设计 第二版》 学习笔记6 -------- 深入函数

-- 第6章 深入函数 -- 函数是一种"第一类值",他们具有特定的"词法域" -- "第一类值":与其他传统类型的值具有相同的权利.例如:存储到变量/table中,作为实参传递给函数或者作为其他函数的返回值 -- "词法域":一个函数可以嵌套在另一个函数中,内部函数可以反问外部函数的变量. local function testFun(x) return 2 * x end -- 函数定义方式1 local testFun

Lua程序设计之深入函数

先看一个函数: function derivative(f,delta) delta = delta or1e-4 return function(x) return (f(x+delta)-f(x))/delta end end 对特定的函数f调用derivative(f)将(近似地)返回其导数,例如 c=derivative(math.sin) print(math.cos(10),c(10))  --c(10)这样的调用相当于derivative(math.sin)(10) 这个例子最让我

第六章 深入理解函数 Lua程序设计笔记

--第六章 深入理解函数Lua中函数是"第一类值",与其他传统类型有相同的权利:可以储存到变量或table中,可以作为函数实参传递,还可以作为函数的返回值. 函数的标准定义: foo = function(x) return x*2 end 一个函数定义实际上就是一条赋值语句,这条语句创建了一种类型为"函数"的值,并将这个值赋予一个变量. --6.1closure(闭合函数) function newCounter() local i = 0 return func

Lua 常用函数 一

http://blog.csdn.net/xuzhonghai/article/details/7239195 lua_getallocf lua_Alloc lua_getallocf (lua_State *L, void **ud); 返回给定状态机的内存分配器函数.如果 ud 不是 NULL ,Lua 把调用lua_newstate 时传入的那个指针放入*ud . lua_getfenv void lua_getfenv (lua_State *L, int index); 把索引处值的

尾调用优化

参考:http://www.ruanyifeng.com/blog/2015/04/tail-call.html 感谢阮老师. 尾调用的概念非常简单,一句话就能说清楚,就是指某个函数的最后一步是调用另一个函数. //正确的尾调用 function f(x) { if (x > 0) { return m(x) } return n(x); } function f(x){ return g(x); } //非尾调用 // 情况一 function f(x){ let y = g(x); retu

尾调用

转自: http://www.ruanyifeng.com/blog/2015/04/tail-call.html https://stackoverflow.com/questions/310974/what-is-tail-call-optimization 一.什么是尾调用? 尾调用的概念非常简单,一句话就能说清楚,就是指某个函数的最后一步是调用另一个函数. function f(x) {returng(x);} 上面代码中,函数f的最后一步是调用函数g,这就叫尾调用. 以下两种情况,都不

栈溢出 缓冲区溢出的一种 缓冲区以外的存储单元被改写 优化方法之一:尾调用

个人:尾调用时函数式编程的一个重要概念, 栈溢出: 函数调用会在内存形成一个"调用记录",又称"调用帧"(call frame),保存调用位置和内部变量等信息.如果在函数A的内部调用函数B,那么在A的调用帧上方,还会形成一个B的调用帧.等到B运行结束,将结果返回到A,B的调用帧才会消失.如果函数B内部还调用函数C,那就还有一个C的调用帧,以此类推.所有的调用帧,就形成一个"调用栈"(call stack).递归调用非常耗内存. 尾调用: 就是指某

函数式编程-尾递归、尾调用

一.什么是尾调用? 尾调用的概念非常简单,一句话就能说清楚,就是指某个函数的最后一步是调用另一个函数. function f(x){ return g(x); } 上面代码中,函数f的最后一步是调用函数g,这就叫尾调用. 以下两种情况,都不属于尾调用. // 情况一 function f(x){ let y = g(x); return y; } // 情况二 function f(x){ return g(x) + 1; } 上面代码中,情况一是调用函数g之后,还有别的操作,所以不属于尾调用,

尾调用优化和尾递归改写

1 尾调用 尾调用就是指某个函数的最后一步是调用另一个函数. # 是尾调用 def f(x): return g(x) # 不是尾调用,因为调用函数后还要执行加法,加法才是最后一步操作 def f(x): return 1+g(x) 2 尾调用优化 函数调用有一个调用栈,栈内保存了这个函数内部的变量信息.函数掉用就是切换不同的调用帧,从而保证每个函数有独立的运行环境.因为尾调用是函数的最后一步操作,所以在进入被尾调用函数之前并不需要保留外层函数的运行时环境,因为调用位置.内部变量等信息都不会再用