Lua 50 参考手册.docx

上传人:b****6 文档编号:7040514 上传时间:2023-01-16 格式:DOCX 页数:66 大小:79.94KB
下载 相关 举报
Lua 50 参考手册.docx_第1页
第1页 / 共66页
Lua 50 参考手册.docx_第2页
第2页 / 共66页
Lua 50 参考手册.docx_第3页
第3页 / 共66页
Lua 50 参考手册.docx_第4页
第4页 / 共66页
Lua 50 参考手册.docx_第5页
第5页 / 共66页
点击查看更多>>
下载资源
资源描述

Lua 50 参考手册.docx

《Lua 50 参考手册.docx》由会员分享,可在线阅读,更多相关《Lua 50 参考手册.docx(66页珍藏版)》请在冰豆网上搜索。

Lua 50 参考手册.docx

Lua50参考手册

Lua5.0参考手册

作者:

RobertoIerusalimschy,LuizHenriquedeFigueiredo,WaldemarCeles

Copyright©2003Tecgraf,PUC-Rio.Allrightsreserved.

译者:

ShiningRayNicholas@NirvanaStudio

给予支持

1-绪论

Lua是一种为支持有数据描述机制的一般过程式编程语言而设计的扩展编程语言。

它同样可以对面向对象语言、函数式程序设计(FunctionalProgramming,如Lisp)以及数据驱动编程(data-drivenprogramming)提供很好的支持。

它的目标是被用作一种强大的、轻型的配置语言。

Lua目前已经被实现为一个扩展库,是用cleanC(ANSIC/C++的一个通用子集)编写的。

作为一个扩展语言,Lua没有"Main"函数的概念:

它仅仅是嵌入一个宿主程序进行工作,可以称之为嵌入式编程或者简单的说是宿主编程。

这个宿主程序可以调用函数来执行Lua的代码片断,可以设置和读取Lua的变量,可以注册C函数让Lua代码调用。

Lua的能力可以扩展到更大范围,在不同的领域内,这样就在同样的语法框架下创建了你自定义的编程语言。

Lua的发行版包括一个独立的嵌入式程序,lua,他使用Lua的扩展库来提供一个完全的Lua解释器。

Lua是自由软件,通常不提供任何担保,如它的版权说明中叙述的那样。

手册中描述的实现在Lua的官方网站可以找到,www.lua.org。

如果需要知道Lua设计背后的一些决定和讨论,可以参考以下论文,它们都可以在Lua的网站上找到。

∙R. Ierusalimschy,L. H. deFigueiredo,andW. Celes.Lua---anextensibleextensionlanguage.Software:

Practice&Experience26#6(1996)635-652.

∙L. H. deFigueiredo,R. Ierusalimschy,andW. Celes.Thedesignandimplementationofalanguageforextendingapplications.ProceedingsofXXIBrazilianSeminaronSoftwareandHardware(1994)273-283.

∙L. H. deFigueiredo,R. Ierusalimschy,andW. Celes.Lua:

anextensibleembeddedlanguage.Dr.Dobb'sJournal21#12(Dec1996)26-33.

∙R. Ierusalimschy,L. H. deFigueiredo,andW. Celes.Theevolutionofanextensionlanguage:

ahistoryofLua,ProceedingsofVBrazilianSymposiumonProgrammingLanguages(2001)B-14-B-28.

Lua在葡萄牙语中的意思是“月亮”,发音是LOO-ah。

2-语言

这一章将描述Lua的词法、语法和语义结构。

换句话说,这一章会讲什么标记是合法的,他们是如何组合的,以及他们的组合是什么含义。

语言结构会使用常用的扩展BNF范式来解释,如{a} 表示0或多个a,[a] 表示a是可选的(0个或1个)。

非终端字体(不能显示的)用斜体表示,关键字是粗体,其他终端符号用typewriter(等宽)字体,并用单引号引出。

2.1-词法约定

Lua中的标识符(Identifiers)可以是任意的数字、字符和下划线“_”,但不能以数字开头。

这条规则符合大多数编程语言中的标识符的定义。

(字符的具体定义要根据系统的地区设置:

任何区域设置可以认同的字母表中的字母都可以用在标识符中。

下面的关键字(keywords)为保留关键字不可以作为标识符出现:

andbreakdoelseelseif

endfalseforfunctionif

inlocalnilnotor

repeatreturnthentrueuntilwhile

Lua对大小写敏感:

and是一个保留字,但是And和AND是两个不一样的、但都合法的标识符。

习惯上来说,以下划线开始且后面跟着大写字母的标识符(例如_VERSION)是为Lua内部变量所保留的。

下面的字符(串)是其他的一些标记:

+-*/^=

~=<=>=<>==

(){}[]

;:

......

字符串(Literalstrings)以单引号或者双引号定界,同时可以包含以下C语言风格的转义字符:

∙\a---铃声(bell)

∙\b---回退(backspace)

∙\f---formfeed

∙\n---新行(newline)

∙\r---回车(carriagereturn)

∙\t---水平制表符(horizontaltab)

∙\v---垂直制表符(verticaltab)

∙\\---反斜杠(backslash)

∙\"---双引号(quotationmark)

∙\'---单引号(apostrophe)

∙\[---左方括号(leftsquarebracket)

∙\]---右方括号(rightsquarebracket)

另外,一个`\newline´(一个反斜杠加上一个真正的换行符)会导致字符串内的分行。

字符串中的字符也可以使用转义字符`\ddd´通过数字值来指定。

ddd是最多为3个十进制数字的序列。

Lua中的字符串也可以包含8进制数字,包括嵌入零,它可以表示为`\0´。

字符串也可以用双方括号来定界[[···]]。

这种括号方式的语法,字符串可以跨越多行,也可以包含嵌套的,同时不会转义任何序列。

方便起见,当开始的`[[´后面紧跟着一个换行符的话,这个换行符不会包括在字符串内。

举个例子:

在一个使用ASCII编码(其中`a´的编码是 97,换行符是 10,字符`1´是 49)的系统中,以下四种格式得到的都是同一个字符串:

(1)"alo\n123\""

(2)'\97lo\10\04923"'

(3)[[alo

123"]]

(4)[[

alo

123"]]

数值常量(Numericalconstants)可以有一个可选的底数部分和一个可选的指数部分。

以下是有效的数值常量:

33.03.1416314.16e-20.31416E1

注释(Comments)可以在任何地方出现,必须在最前面加上双减号(--)。

如果紧接着--的文本不是[[,那么会认为是一个短注释(shortcomment),这一行往后到行尾都是注释。

否则,会认为是一个常注释(longcomment),注释直到相应的]]结束。

长注释可以跨越多行,同时可以包含嵌套的[[···]]括号对。

为了方便起见,文件的第一行如果是以#开始,这个机制允许Lua在Unix系统中用做一个脚本解释器(见6)。

2.2-值和类型

Lua是一种动态类型语言(dynamicallytypedlanguage)。

这意味着变量是没有类型的;只有值才有。

语言中没有类型定义。

所有的值都包含他自身的类型。

Lua中有八种基本类型:

nil,boolean,number,string,function,userdata,thread和table。

Nil空类型只对应nil值,他的属性和其他任何值都有区别;通常它代表没有有效的值。

Boolean布尔类型有两种不同的值falseandtrue。

在Lua中,nilandfalse代表成假条件;其他任何值都代表成真条件。

Number数字类型表示实数(双精度浮点数)。

(构建Lua解释器时也可以很容易地用其他内部的表示方式表示数字,如单精度浮点数或者长整型)。

String字符串类型表示一个字符的序列。

Lua字符串可以包含8位字符,包括嵌入的('\0')(见2.1)。

函数是Lua中的第一类值(first-classvalues)。

也就是说函数可以保存在变量中,当作参数传递给其他函数,或者被当作结果返回。

Lua可以调用(和处理)Lua写的函数和C写的函数(见2.5.7)。

用户数据类型(userdata)提供了让任意C数据储存在Lua变量中的功能。

这种类型直接对应着一块内存,Lua中也没有任何预先定义的操作,除了赋值和一致性比较。

然而,通过使用元表(metatables),程序员可以定义处理userdata的操作。

(见2.8)。

Userdata值不能在Lua中建立或者修改,只能通过C API。

这保证了宿主程序的数据完整性。

线程(thread)类型代表了相互独立的执行线程,用来实现同步程序。

表(table)类型实现了联合数组,也就是说,数组不仅可以使用数字,还能使用其他的值(除了nil)。

而且,tables可以是互异的(heterogeneous),他们可以保存任何类型的值(除了nil)。

Tables是Lua中唯一的数据结构机制;他们可以用来表示一般数组,特征表,集合,记录,图,树等等。

如果要表示记录,Lua使用字段名作为索引。

语言支持a.name这种比较优美的表示方式,还有a["name"]。

在Lua中有几种建立表的简便方法(见2.5.6)。

就像索引一样,表字段的值也可以是任何类型(除了nil)。

特别需要注意地是,由于函数是第一型的值,表字段也可以包含函数。

这样表也可以支持方法(methods)(见2.5.8)。

表,函数,和用户数据类型的值都是对象(objects):

变量不会包含他们的实际值,只是一个他们的引用(references)。

赋值,参数传递和函数返回只是操作这些值的引用,这些操作不会暗含任何拷贝。

库函数type返回一个字符串描述给出值所表示的类型(见5.1)。

2.2.1-类型转换

Lua提供运行时的数字和字符串值得自动转换。

任何对字符串的算术操作都会现尝试把字符串转换成数字,使用一般规则转换。

反过来,当一个数值用在需要字符串的地方时,数字会自动转换成字符串,遵循一种合理的格式。

如果要指定数值如何转换成字符串,请使用字符串库中的format函数(见5.3)。

2.3-变量

变量是储存值的地方。

Lua中有三种不同的变量:

全局变量,局部变量和表字段。

一个名称可以表示全局变量或局部变量(或者一个函数的正式参数,一种局部变量的特殊形式):

var:

:

=Name

Lua假设变量是全局变量,除非明确地用local进行声明(见2.4.7)。

局部变量有词义范围(lexicallyscoped):

局部变量可以被在它们范围内的函数自由访问(见2.6)。

在变量第一次赋值之前,它的值是nil。

方括号用于对表进行检索:

var:

:

=prefixexp`[´exp`]´

第一个表达式(prefixexp)结果必须是表;第二个表达式(exp)识别表中一个特定条目。

给出表的表达式有一个限制语法;详细见2.5。

var.NAME语法是var["NAME"]的较好形式:

var:

:

=prefixexp`.´Name

访问全局变量和表字段的实质可以通过元表进行改变。

对索引变量t[i]的访问等同于调用gettable_event(t,i)。

(关于gettable_event的完整描述见2.8。

这个函数并没有在Lua中定义,也无法调用。

我们在这里仅仅用来解释原理)。

所有的全局变量存在一个普?

ǖ腖ua表中,称之为环境变量表(environmenttables)或简称环境(environments)。

由C写的并导入到Lua中的函数(C函数)全部共享一个通用全局环境(globalenvironment)。

Lua写的每个函数(aLua函数)都有一个它自己的环境的引用,这样这个函数中的所有的全局变量都会指向这个环境变量表。

当新创建一个函数时,它会继承创建它的函数的环境。

要改变或者获得Lua函数的环境表,可以调用setfenvorgetfenv(见5.1)。

访问全局变量x等同于_env.x,又等同于

gettable_event(_env,"x")

_env是运行的函数的环境。

(_env变量并没有在Lua中定义。

我们这里仅仅用来解释原理)

2.4-语句

Lua支持一种很通俗的语句集,和Pascal或者C中的很相似。

他包括赋值,控制结构,过程调用,表构造和变量声明。

2.4.1-语句段

Lua执行的最小单元称之为一个段(chunk)。

一段语句就是简单的语句的序列,以顺序执行。

每一个语句后面都可以加上一个分号(可选):

chunk:

:

={stat[`;´]}

Lua将语句段作为一个匿名函数(见2.5.8)的本体进行处理。

这样,语句段可以定义局部变量或者返回值。

一段语句可以储存在文件内或者宿主程序的一个字符串中。

当语句段被执行时,他首先被预编译成虚拟机使用的字节码,然后虚拟机用一个解释器执行被编译的代码。

语句段也可以被预编译为二进制代码;详情参看luac程序。

源代码和编译形态可以互相转换;Lua自动监测文件类型然后作相应操作。

2.4.2-语句块

一个语句块是一系列语句;从语句构成上来看,语句块等同于语句段:

block:

:

=chunk

一个语句块可以明确定界来替换单个语句:

stat:

:

=doblockend

显式语句块可以很好地控制变量的声明范围。

显示语句块有时也常会在另一个语句块的中间添加return或break语句(见2.4.4)。

2.4.3-赋值

Lua允许多重赋值。

因此,赋值的语法定义为:

等号左边是一个变量表,右边是一个表达式表。

两边的表中的元素都用逗号分隔开来:

stat:

:

=varlist1`=´explist1

varlist1:

:

=var{`,´var}

explist1:

:

=exp{`,´exp}

我们将在2.5讨论表达式。

在赋值之前,值的表长度会被调整为和变量的表一样。

如果值比需要的多,多出的值就会被扔掉。

如果值的数量不够,就会用足够多的nil来填充表直到满足数量要求。

如果表达式表以一个函数调用结束,那么在赋值之前,函数返回的所有的值都会添加到值的表中(除非把函数调用放在括号里面;见2.5)。

赋值语句首先计算出所有的表达式,然后才会执行赋值,所以代码:

i=3

i,a[i]=i+1,20

设置a[3]为20,但不影响a[4]。

因为在a[i]中的i在赋值为4之前是等于3。

同样的,下面这行:

x,y=y,x

可以交换x和y的值。

对全局变量和表字段的赋值可以看作是通过元表进行的。

对一个索引变量的赋值t[i]=val等同于settable_event(t,i,val)。

(settable_event详细介绍参看2.8,Lua中并未定义该函数,他也无法直接调用。

我们这里只是用它来进行解释。

对全局变量的赋值x=val等同于赋值语句_env.x=val,像前面也等同于:

settable_event(_env,"x",val)

_env是运行函数的环境。

(_env变量并未在Lua中定义。

我们这里只是用来进行解释。

2.4.4-控制结构

控制结构if,while和repeat具有通用的含义和类似的语法:

stat:

:

=whileexpdoblockend

stat:

:

=repeatblockuntilexp

stat:

:

=ifexpthenblock{elseifexpthenblock}[elseblock]end

Lua也有for语句,有两种格式(见2.4.5)。

控制结构的条件表达式exp可以返回任意值。

false和nil都表示假。

所有其他的值都认为是真(特别要说明的:

数字0和空字符串也表示真)。

语句return用来从函数或者是语句段中返回一个值。

函数和语句段都可以返回多个值,所以return语句的语法为:

stat:

:

=return[explist1]

break语句可以用来终止while,repeat或者for循环的执行,直接跳到循环后面的语句。

stat:

:

=break

break结束最里面的一个循环。

由于语法的原因,return和break语句只能作为语句块的最后一个语句。

如果确实需要在语句块的中间使用return或者break,需要使用一个显示语句块:

`doreturnend´和`dobreakend´,这样现在return和break就成为他们(内部)语句块中的最后一个语句了。

实际上,这两种用法一般只用在调试中。

2.4.5-For语句

for语句有两种形式:

数值形式和一般形式。

数值形式的for循环根据一个控制变量用算术过程重复一语句块。

语法如下:

stat:

:

=forName`=´exp`,´exp[`,´exp]doblockend

block语句块根据name以第一个exp的值开始,直到他以第三个exp为步长达到了第二个exp。

一个这样的for语句:

forvar=e1,e2,e3doblockend

等价于一下代码:

do

localvar,_limit,_step=tonumber(e1),tonumber(e2),tonumber(e3)

ifnot(varand_limitand_step)thenerror()end

while(_step>0andvar<=_limit)or(_step<=0andvar>=_limit)do

block

var=var+_step

end

end

注意:

∙三种控制表达式只会被计算一次,在循环开始之前。

他们的结果必须是数值。

∙_limit和_step是不可见的变量。

这里只是为了进行解释。

∙如果你在程序块内给var赋值,结果行为将会不确定。

∙如果没有给出第三个表达式(步长),那么默认为1。

∙你可以使用break来退出for循环。

∙循环变量var是局部变量;你不可以在for循环结束之后继续使用。

如果你需要使用这个值,请在退出循环之前把它们传给其他变量。

for的语句的一般形式是操作于函数之上的,称之为迭代器(iterators)。

每一个迭代过程,它调用迭代函数来产生新的值,直到新的值是nil。

一般形式for循环有如下语法:

stat:

:

=forName{`,´Name}inexplist1doblockend

一个这样的for语句

forvar_1,...,var_ninexplistdoblockend

等同于以下代码:

do

local_f,_s,var_1=explist

localvar_2,...,var_n

whiletruedo

var_1,...,var_n=_f(_s,var_1)

ifvar_1==nilthenbreakend

block

end

end

注意:

∙explist只会计算一次。

他的结果是一个迭代函数,一个状态,和给第一个迭代变量的一个初始值。

∙_f和_s是不可见的变量。

这里只是用来进行解释说明。

∙如果你在语句块中给var_1赋值,那么行为就会变得不确定。

∙你可以使用break来退出for循环。

∙循环变量var_i是局部变量;你不可以在for循环结束之后继续使用。

如果你需要使用这个值,请在退出循环之前把它们传给其他变量。

2.4.6-语句式函数调用

如果要忽略可能的影响,函数调用可以按照语句执行:

stat:

:

=functioncall

I在这里,所有的返回值都会被忽略。

函数调用将在2.5.7详细解释。

2.4.7-局部变量声明

局部变量可以在语句块中任何地方声明。

声明时也可以添加一个初始赋值:

stat:

:

=localnamelist[`=´explist1]

namelist:

:

=Name{`,´Name}

如果出现初始赋值,他的语法和多重赋值语句一样(见2.4.3)。

否则,所有的变量都会初始化为nil。

一个语句段也是一个语句块(见2.4.1),所以语句段之内的任何显式语句块之外也可以声明局部变量。

这种局部变量在语句段结束就会销毁。

局部变量的可见规则会在2.6解释。

2.5-表达式

Lua中有以下几种基本表达式:

exp:

:

=prefixexp

exp:

:

=nil|false|true

exp:

:

=Number

exp:

:

=Literal

exp:

:

=function

exp:

:

=tableconstructor

prefixexp:

:

=var|functioncall|`(´exp`)´

数字和字符串已经在2.1中解释;变量在2.3中解释;函数定义在2.5.8;函数调用在2.5.7;表构造器在2.5.6。

一个用括号括起的表达式只会返回一个值。

这样,(f(x,y,z))将只会返回单一的一个值,即使f可以返回多个值,((f(x,y,z))的值将是f返回的第一个值或者如果f没有返回任何值就是nil)。

表达式也可以使用各种算术运算符,关系运算符和逻辑运算符,下面几节就会讲到。

2.5.1-算术运算符

Lua支持常见的几种运算符:

二元+(加),-(减),*(乘),/(除),以及^(指数运算);一元-(负号)。

如果操作数是数字,或者是可以转换成数字的字符串(见2.2.1),那么所有的操作都和算术意义上的运算一致(除了指数)。

指数运算其实是调用一个全局函数__pow,否则一个合适的元方法将会被调用(见2.8)。

标准数学库定义了函数__pow,给出了指数运算的定义(见5.5)。

2.5.2-

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工作范文 > 行政公文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1