您好,欢迎访问三七文档
Lua5.1参考手册byRobertoIerusalimschy,LuizHenriquedeFigueiredo,WaldemarCeles云风译©2006Lua.org,PUC-Rio.Allrightsreserved.1-介绍Lua是一个扩展式程序设计语言,它被设计成支持通用的过程式编程,并有相关数据描述的设施。Lua也能对面向对象编程,函数式编程,数据驱动式编程提供很好的支持。它可以作为一个强大、轻量的脚本语言,供任何需要的程序使用。Lua以一个用cleanC写成的库形式提供。(所谓CleanC,指的ANSIC和C++中共通的一个子集)作为一个扩展式语言,Lua没有main程序的概念:它只能嵌入一个宿主程序中工作,这个宿主程序被称作embeddingprogram或简称为host。宿主程序可以通过调用函数执行一小段Lua代码,可以读写Lua变量,可以注入C函数让Lua代码调用。这些扩展的C函数,可以大大的扩展了Lua可以处理事务的领域,这样就可以订制出各种语言,而它们共享一个统一的句法格式的框架。Lua的官方发布版就包含了一个叫做lua的简单的宿主程序,它用Lua库提供了一个保证独立的Lua解释器。Lua是一个自由软件,它的使用许可决定了对它的使用过程一般没有任何保证。这份手册中描述的东西的实现,可以在Lua的官方网站找到,跟其它的许多参考手册一样,这份文档有些地方比较枯燥。关于Lua的设计想法的探讨,可以看看Lua网站上提供的技术论文。有关用Lua编程的细节介绍,可以读一下Roberto的书,ProgramminginLua(SecondEdition)。2-语言这一节从词法、语法、句法上描述Lua。换句话说,这一节描述了哪些token(符记)是有效的,它们如何被组合起来,这些组合方式有什么含义。关于语言的构成概念将用常见的扩展BNF表达式写出。也就是这个样子:{a}意思是0或多个a,[a]意思是一个可选的a。非最终的符号会保留原来的样子,关键字则看起来像这样kword,其它最终的符号则写成`=´。完整的Lua语法可以在本手册最后找到。2.1-词法约定Lua中用到的名字(也称作标识符)可以是任何非数字开头的字母、数字、下划线组成的字符串。这符合几乎所有编程语言中关于名字的定义。(字母的定义依赖于当前环境:系统环境中定义的字母表中的字母都可以被用于标识符。)标识符用来命名变量,或作为表的域名。下面的关键字是保留的,不能用作名字:andbreakdoelseelseifendfalseforfunctionifinlocalnilnotorrepeatreturnthentrueuntilwhileLua是一个大小写敏感的语言:and是一个保留字,但是And和AND则是两个不同的合法的名字。一般约定,以下划线开头连接一串大写字母的名字(比如_VERSION)被保留用于Lua内部全局变量。下面这些是其它的token:+-*/%^#==~====()[]{};:,......字符串既可以用一对单引号引起,也可以是双引号,里面还可以包含类似C的转义符:'\a'(响铃),'\b'(退格),'\f'(表单),'\n'(换行),'\r'(回车),'\t'(横向制表),'\v'(纵向制表),'\\'(反斜杠),'\'(双引号),以及'\''(单引号)。而且,如果在一个反斜杠后跟了一个真正的换行符,其结果就是在字符串中产生一个换行符。我们还可以用反斜杠加数字的形式\ddd来描述一个字符。这里,ddd是一串最多三位的十进制数字。(注意,如果需要在这种描述方法后接一个是数字的字符,那么反斜杠后必须写满三个数字。)Lua中的字符串可以包含任何8位的值。包括用'\0'表示的零。只有在你需要把不同的引号、换行、反斜杠、或是零结束符这些字符置入字符串时,你才必须使用转义符。别的任何字符都可以直接写在文本里。(一些控制符可以会影响文件系统造成某些问题,但是不会引起Lua的任何问题。)字符串还可以用一种长括号括起来的方式定义。我们把两个正的方括号间插入n个等号定义为第n级正长括号。就是说,0级正的长括号写作[[,一级正的长括号写作[=[,如此等等。反的长扩展也作类似定义;举个例子,4级反的长括号写作]====]。一个长字符串可以由任何一级的正的长括号开始,而由第一个碰到的同级反的长括号结束。整个词法分析过程将不受分行限制,不处理任何转意符,并且忽略掉任何不同级别的长括号。这种方式描述的字符串可以包含任何东西,当然特定级别的反长括号除外。另一个约定是,当正的长括号后面立即跟了一个换行符,这个换行符就不包含在这个字符串内。举个例子,假设一个系统使用ASCII码(这时,'a'编码为97,换行符编码为10,'1'编码为49),下面五种方式描述了完全相同的字符串:a='alo\n123'a=alo\n123\a='\97lo\10\04923'a=[[alo123]]a=[==[alo123]==]数字常量可以分两部分写,十进制底数部分和十进制的指数部分。指数部分是可选的。Lua也支持十六进制整数常量,只需要在前面加上前缀0x。下面是一些合法的数字常量的例子:33.03.1416314.16e-20.31416E10xff0x56注释可以在除字符串内的任何地方,是以两横(--)开始。如果跟在两横后面的不是一个长括号,这就是一个短注释,它的作用范围直到行末;否则就是一个长注释,其作用范围直到遇到反的长括号。长注释通常被用来临时屏蔽代码块。2.2-值与类型Lua是一种动态类型语言。这意味着变量没有类型,只有值才有类型。语言中不存在类型定义。而所有的值本身携带它们自己的类型信息。Lua中的所有值都是一致(first-class)的。这意味着所有的值都可以被放在变量里,当作参数传递到另一个函数中,并被函数作为结果返回。Lua中有八种基本类型:nil,boolean,number,string,table,userdata,function,thread.Nil类型只有一种值nil,它的主要用途用于标识和别的任何值的差异;通常,当需要描述一个无意义的值时会用到它。Boolean类型只有两种值:false和true。nil和false都能导致条件为假;而另外所有的值都被当作真。Number表示实数(双精度浮点数)。(编译一个其它内部数字类型的Lua解释器是件很容易的事;比如把内部数字类型改作单精度浮点数或长整型。参见文件luaconf.h。)String表示一串字符的数组。Lua是8-bitclean的:字符串可以包含任何8位字符,包括零结束符('\0')(参见§2.1)。Lua可以调用(和处理)用Lua写的函数以及用C写的函数(参见§2.5.8).userdata类型用来将任意C数据保存在Lua变量中。这个类型相当于一块原生的内存,除了赋值和相同性判断,Lua没有为之预定义任何操作。然而,通过使用metatable(元表),程序员可以为userdata自定义一组操作(参见§2.8)。userdata不能在Lua中创建出来,也不能在Lua中修改。这样的操作只能通过CAPI。这一点保证了宿主程序完全掌管其中的数据。thread类型用来区别独立的执行线程,它被用来实现coroutine(协同例程)(参见§2.11)。不要把Lua线程跟操作系统的线程搞混。Lua可以在所有的系统上提供对coroutine的支持,即使系统并不支持线程。table类型实现了一个关联数组。也就是说,数组可以用任何东西(除了nil)做索引,而不限于数字。table可以以不同类型的值构成;它可以包含所有的类型的值(除nil外)。table是lua中唯一的一种数据结构;它可以用来描述原始的数组、符号表、集合、记录、图、树、等等。用于表述记录时,lua使用域名作为索引。语言本身采用一种语法糖,支持以a.name的形式表示a[name]。有很多形式用于在lua中创建一个table(参见§2.5.7)。跟索引一样,table每个域中的值也可以是任何类型(除nil外)。特别的,因为函数本身也是值,所以table的域中也可以放函数。这样table中就可以有一些methods了(参见see§2.5.9)。Table,function,thread和(full)userdata这些类型的值是所谓的对象:变量本身并不会真正的存放它们的值,而只是放了一个对对象的引用。赋值,参数传递,函数返回,都是对这些对象的引用进行操作;这些操作不会在暗地里做任何性质的拷贝。库函数type可以返回一个描述给定值的类型的字符串。2.2.1-强制转换Lua提供运行时“字符串到数字”的自动转换。任何对字符串的数学运算操作都会尝试用一般的转换规则把这个字符串转换成一个数字。相反,无论何时,一个数字需要作为字符串来使用时,数字都会以合理的格式转换为字符串。需要完全控制数字怎样转换为字符串,可以使用字符串库中的format函数(参见string.format)。2.3-变量写上变量的地方意味着当以其保存的值来替代之。Lua中有三类变量:全局变量,局部变量,还有table的域。一个单一的名字可以表示一个全局变量,也可以表示一个局部变量(或者是一个函数的参数,这是一种特殊形式的局部变量):var::=NameName就是§2.1中所定义的标识符。任何变量都被假定为全局变量,除非显式的以local修饰定义(参见§2.4.7)。局部变量有其作用范围:局部变量可以被定义在它作用范围中的函数自由使用(参见§2.6)。在变量的首次赋值之前,变量的值均为nil。方括号被用来对table作索引:var::=prefixexp`[´exp`]´对全局变量以及table域之访问的含义可以通过metatable来改变。以取一个变量下标指向的量t[i]等价于调用gettable_event(t,i)。(参见§2.8,有一份完整的关于gettable_event函数的说明。这个函数并没有在lua中定义出来,也不能在lua中调用。这里我们把它列出来只是方便说明。)var.Name这种语法只是一个语法糖,用来表示var[Name]:var::=prefixexp`.´Name所有的全局变量都是放在一个特定Luatable的诸个域中,这个特定的table叫作environment(环境)table或者简称为环境(参见§2.9)。每个函数都有对一个环境的引用,所以一个函数中可见的所有全局变量都放在这个函数所引用的环境表(environmenttable)中。当一个函数被创建出来,它会从创建它的函数中继承其环境,你可以调用getfenv取得其环境。如果想改变环境,可以调用setfenv。(对于C函数,你只能通过debug库来改变其环境;参见§5.9)。对一个全局变量x的访问等价于_env.x,而这又可以等价于gettable_event(_env,x)这里,_env是当前运行的函数的环境。(函数gettable_event的完整说明参见§2.8。这个函数并没有在Lua中定义出来,也不能调用。当然,_env这个变量也同样没有在Lua中定义出来。我们在这里使用它们,仅仅只是方便解释而已。)2.4-语句(Statement)Lua支持惯例形式的语句,它和Pascal或是C很相象。这个集合包括赋值,控制结构,函数调用,还有变量声明。2.4.1-语句组(Chunk)Lua的一个执行单元被称作Chunk。一个Chunk可以是一个或一组语句,它们会被循序的执行。每个语句可以以一个分号结束:chunk::={stat[`;´]}这儿不允许有空的语句,所以';;'是非法的。Lua把一个chunk当作一个拥有不定参数的匿名函数(参见§2.5.9)处理。正是这样,chunk内可以定义局部变量,接收参数,并且返回值。chunk可以被保存在一个文件中,也可以保存在宿主程序的一个字符串中。当一个chunk被执行,首先它
本文标题:Lua编程指南
链接地址:https://www.777doc.com/doc-1909843 .html