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

posted @ 2015-11-23 22:50  Through  阅读(146)  评论(0编辑  收藏  举报