在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
Lua支持“尾调用消除(tail-call elimination)”。 function f (x) return g(x) end 也就是说,当f调用完g之后就再无其他事情可做了。因此在这种情况下,程序就不需要返回那个“尾调用”所在的函数了。所以在“尾调用”之后,程序也不需要保存任何关于该函数的栈(stack)信息了。当g返回时,执行控制权可以直接返回到调用f的那个点上。有一些语言实现(例如Lua解释器)可以得益于这个特点,使得在进行“尾调用”时不好非任何栈空间。将这种实现称为支持“尾调用消除”。 function foo (n) if n > 0 then return foo(n-1) end end 判断当前的调用是一条“尾调用”的准则:一个函数在调用完另一个函数之后,是否就无其他事情需要做了。 function f (x) g(x) end 这个示例的问题在于,当调用完g后,f并不能立即返回,它还需要丢弃g返回的临时结果。类似的,以下所有调用也都不符合上述准则: 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)
function room1 () local move = io.read() if move == "sourth" then return room3() elseif move == "east" then return room2() else print("invalid move") return room1() -- stay in the same room end end function room2() local move = io.read() if move == "sourth" then return room4() elseif move == "west" then return room1() else print("invalid move") return room2() end end function room3() local move = io.read() if move == "north" then return room1() elseif move == "east" then return room4() else print("invalid move") return room3() end end function room4() print("congratulations!") end 通过调用出世房间来开始这个游戏: room1() 若没有“尾调用消除”的话,每次用户的移动都会创建一个新的栈层(stack level),移动若干步之后就有可能会导致栈溢出。而“尾调用消除”则对用户已动的次数没有限制。这是因为每次移动实际上都只是完成一条goto语句到另一个函数,而非传统的函数调用。 |
请发表评论