Lua编程入门-学习笔记2
第6章 深入函数
函数是一种“第一类值(First-Class Value)”,他们具有特定的词法域(lexical scoping)
将表达式“function(x) <body> end”视为一种函数的构造式,就像table的构造式{}一样。
function foo(x) return 2*x end --> foo = funciton(x) return 2*x end
closure(闭包)
非局部变量(non-local variable)
从技术上讲,lua只有closure,而不存在“函数”,函数本身就是一种特殊的closure.
经典示例:
do
local oldOpen = io.open
local access_OK = function(filename, mode)
<检查访问权限>
end
io.open = function(filename, mode)
if access_OK(filename, mode) then
return oldOpen(filename, mode)
else
return nil, "access denied"
end
end
end
非全局的函数
Lua把chunk当前函数处理,在chunk内可以声明局部函数(仅仅在chunk内可见),词法定界保证了包内的其他函数可以调用此函数。
使用前先声明
local fact
local fact = function (n)
if n == 0 then
return 1
else
return n * fact(n-1)
end
end
在定义非直接递归局部函数时要先声明然后定义才可以。
尾调用,其是一种类似在函数结尾的goto调用,当函数最后一个动作是调用另外一个函数时,我们称这种调用尾调用。如:
function f(x) return g(x) end
尾调用之后程序需要在栈中保留关于调用者的任何信息,lua利用这种特性在处理尾调用时不使用额外的栈。 所以尾调用的层次可以无限制。
第七章 迭代器和泛型for
迭代器与闭包
迭代器需要保留上一次成功调用的状态和下一次成功调用的状态,也就是他知道来自于哪里和将要前往哪里。闭包提供的机制可以很容易实现这个任务。
function list_iter (t)
local i = 0
local n = table.getn(t)
return function ()
i = i + 1
if i <= n then return t[i] end
end --返回闭包
end
泛型for的语义
for var1, var2, ... varN in explist do block end
与下面等价
do
local _f, _s, _var = explist -- 迭代函数、状态变量、控制变量
while true do
local var1, var2, ..., varN = _f(_s, _var)
_var = var1
if _var == nil then break end
block
end
end
无状态的迭代器
类似ipairs、pairs实现:
local function iter(a, i)
i = i + 1
local v = a[i]
if v then
return i, v
end
end
function ipairs(t)
return iter, t, 0
end
function pairs(t)
return next, t, nil
end
具有复杂状态的迭代器
local iterator
function allwords()
local state = {line = io.read(), pos = 1}
return iterator, state
end
function iterator(state)
while state.line do
local s, e = string.find(state.line, "%w+", state.pos)
if s then
state.pos = e + 1
return string.sub(state.line, s, e)
else
state.line = io.read()
state.pos = 1
end
end
return nil
end