文档章节

Lua程序设计 非全局的函数

80后小子
 80后小子
发布于 2014/07/23 20:12
字数 792
阅读 296
收藏 5

         由于函数是一种“第一类值”,因此一个显而易见的推论就是,函数不仅可以存储在全局变量中,还可以存储在table的字段和局部变量中。

        大部分Lua库也采用了这种将函数存储在字段中的机制(io.read、math.sin).若要在Lua中创建这种函数,只需将常规的函数语法与table语法结合起来使用即可:

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
function lib.goo (x, y) return x - y end

     只要将一个函数存储到一个局部变量中,即得到了一个“局部函数”,也就是说该函数只能在某个特定的作用域中使用。

     因为Lua是将每个程序块作为一个函数来处理的,所以在一个程序块中声明的函数就是局部函数,这些局部函数只在该程序块中可见。“词法域”确保了程序包中的其他函数可以使用这些局部函数:

local f = function(参数)
   <函数体>
end

local g = function(参数)
   <一些代码>
   f()  -- f在这里是可见的。
   <一些代码>
end
对于这种局部函数的定义,Lua还支持一种“语法糖”:
local function f(参数)
<函数体>
end
在定义递归的局部函数时,像下面这种函数的定义语法是错误的:
local fact = function (n) 
   if n == 0 then return 1
   else return n*fact(n -1)
   end
end
 因为,当Lua编译到函数体中调用fact(n-1)的地方时,由于局部的fact尚未定义完毕,因此这句表达式其实是调用一个全局的fact,而非此函数自身。
 解决办法:
 local fact
 fact = function(n) 
 if n == 0 then return 1
 else return n*fact(n - 1)
   end
 end
 现在函数中的fact调用就表示了局部变量。即使在函数定义时,这个局部变量的值尚未完成定义,但之后在函数执行时,fact则肯定已经拥有了正确的值。

       当Lua展开局部函数定义的“语法糖”时,并不是使用基本函数定义语法。而是对于局部函数定义:

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
然而,在间接递归的情况中,必须使用一个明确的前向声明:
local  f, g  --前向声明
function g ()
   <一些代码>
   f()     
   <一些代码>
 end
 function f ()
  <一些代码>
   g()    
    <一些代码>
 end
 注意:别把第二个函数定义写为“local function f”.如果那样的话,Lua会创建一个全新的局部变量f,而将原来声明的f置于未定义的状态。

© 著作权归作者所有

80后小子
粉丝 5
博文 84
码字总数 23028
作品 0
海淀
程序员
私信 提问
编写C函数的技术-《lua程序设计》 27章 学习

1.数组操作 void luarawgeti(luaState * L ,int index,int key) void luarewseti(luaState * L,int index,int key) index表示table在栈的位置,key表示元素在table中的位置 test.lua内容 tab ......

技术小阿哥
2017/11/26
0
0
Lua程序设计之深入函数

先看一个函数: function derivative(f,delta) delta = delta or1e-4 return function(x) return (f(x+delta)-f(x))/delta end end 对特定的函数f调用derivative(f)将(近似地)返回其导数,......

firekido
2017/07/22
0
0
Lua1.1 Lua 的设计和实现 (一)

说明: 这个文档是 Lua1.1 的 doc 目录里的 lua.ps 文件。 同时这个文档可以这里找到:http://www.lua.org/semish94.html 原文版权归原作者所有,这篇翻译只是作为学习之用。如果翻译有不当之...

晓寒
2014/09/03
398
0
Lua4.0 参考手册(四)4.6-4.8

(接上篇) ------------------- 4.6 可见性和 Upvalue ------------------- 一个函数体可以引用它自己的局部变量(包括它的参数)和全局变量,只要它们没有被函数中同名的局部变量所隐藏(s...

晓寒
2014/11/05
131
0
Lua 学习笔记(2) 类型与值、表达式、语句、迭代器、泛型for

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/l773575310/article/details/82715966 Lua 学习笔记(2) 类型与值、表达式、语句 参考书籍: 《Lua程序设计》...

ChiLi_Lin
2018/09/15
0
0

没有更多内容

加载失败,请刷新页面

加载更多

关于AsyncTask的onPostExcute方法是否会在Activity重建过程中调用的问题

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/XG1057415595/article/details/86774575 假设下面一种情况...

shzwork
今天
7
0
object 类中有哪些方法?

getClass(): 获取运行时类的对象 equals():判断其他对象是否与此对象相等 hashcode():返回该对象的哈希码值 toString():返回该对象的字符串表示 clone(): 创建并返此对象的一个副本 wait...

happywe
今天
6
0
Docker容器实战(七) - 容器中进程视野下的文件系统

前两文中,讲了Linux容器最基础的两种技术 Namespace 作用是“隔离”,它让应用进程只能看到该Namespace内的“世界” Cgroups 作用是“限制”,它给这个“世界”围上了一圈看不见的墙 这么一...

JavaEdge
今天
8
0
文件访问和共享的方法介绍

在上一篇文章中,你了解到文件有三个不同的权限集。拥有该文件的用户有一个集合,拥有该文件的组的成员有一个集合,然后最终一个集合适用于其他所有人。在长列表(ls -l)中这些权限使用符号...

老孟的Linux私房菜
今天
7
0
面试套路题目

作者:抱紧超越小姐姐 链接:https://www.nowcoder.com/discuss/309292?type=3 来源:牛客网 面试时候的潜台词 抱紧超越小姐姐 编辑于 2019-10-15 16:14:56APP内打开赞 3 | 收藏 4 | 回复24 ...

MtrS
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部