Depth function 2
Non-Global functions
- The first value is a function, the function can be stored in global variables, local variables, table field
- Most lua library function table stored in the field
Lib = {}
Lib.foo = function (x, y)
return x + y
end
Lib.goo = function (x, y)
return x - y
end
Lib = {
foo = function (x, y) return x + y end,
goo = function (x, y) return x - y end
}
Lib = {}
function Lib.foo(x, y) return x + y end
fucntion Lib.goo(x, y) return x - y end
- A function stored in a local variable, namely "partial function"
- This function can only use the corresponding scope for the "package"
package
is useful
- lua each block as a function to process a
- Functions declared in the program block is a local function, visible only in the block
- Lexical domain ensure other functions may be used to package these local functions.
local f = function (<参数列表>)
<函数体>
end
local g = function (<参数列表>)
<函数代码>
f(实参) -- 可以调用 f
<函数代码>
end
local function f(<参数列表>)
<函数体>
end
-- 阶乘 n! = n * (n - 1) * (n - 2) * ... 1
local fact = function (n) -- 错误的递归函数定义
if n == 0 then
return 1
else
return n * fact(n - 1) -- fact 函数定义未完成,调用的是 fact 全局变量,而不是 fact 函数本身
end
end
-- 正确的递归函数定义
local fact
fact = function (n)
if n == 0 then
return 1
else
return n * fact(n - 1)
end
end
local function foo(<参数>) <函数体> end
-- Lua 将其展开为:
local foo
foo = function (<参数>) <函数体> end
-- 正确的函数定义,对于间接递归无效
local function fact (n)
if n == 0 then
return 1
else
return n * fact(n - 1)
end
end
-- 递归就是函数调用函数本身
-- 间接递归就是 a 函数调用 b 函数而 b 函数又调用了 a 函数
-- 间接递归需要使用明确的前向声明
local f, g
function g ()
<函数代码>
f()
<函数代码>
end
function f() -- 不要加 local 如果加上那么在函数 g 中引用的就处于未定义状态,因为 lua 会创建一个全新的局部变量 f
<函数代码>
g()
<函数代码>
end
Right tail calls
- "Last call" is similar to the
goto
function call
- When a function call is the last action of another function when the call is a "tail calls"
function f (x)
<函数代码>
return g(x)
end
- After f calls g finished there will be no other code execution
- In this case, the program does not need to return to the function where the "tail calls" the
- After "Last call" program you do not need to save any information about the function of the stack
- When g return, execution control can be returned directly on the point of calling f
- Do not spend any time so that the stack space "Last call" making
- This implementation is called "tail call elimination."
-- 尾调用函数
function foo(n)
if n > 0 then
return foo(n - 1)
end
end
-- 调用完 g 函数后还进行了加法操作,非尾调用
return g(x) + 1
-- 有 or 操作,必须调整为一个返回值
retrun x or g(x)
-- 函数外嵌套一个括号,强制其只返回一个返回值
return (g(x))
-- 尾调用标准格式
return <func>(<args>)
-- 是一个尾调用
-- 调用前会对 <func> 及其参数求值
return x[i].foo(x[j] + a * b, i + j)
Write state machine
- A typical example: Maze
-- 四间房间的迷宫
function room1()
local move = io.read()
if move == "south" then
return room3()
elseif move == "east" then
return room2()
else
print("invalid move")
return room1()
end
end
function room2()
local move = io.read()
if move == "south" 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
- If there is no "tail call elimination," every time a user moves will create a new layer stack may be a stack overflow after several steps
- "Last call to eliminate" more often mobile users without any restrictions
- Because every move is actually just completed a
goto
sentence to another function