收藏 分销(赏)

编程语言教程programming in lua中文.pdf

上传人:曲**** 文档编号:10581619 上传时间:2025-06-03 格式:PDF 页数:241 大小:15.11MB
下载 相关 举报
编程语言教程programming in lua中文.pdf_第1页
第1页 / 共241页
编程语言教程programming in lua中文.pdf_第2页
第2页 / 共241页
点击查看更多>>
资源描述
Programming in Lua扬起帆,让我们一同踏上Lua的学习之旅本书的翻译,是中朋友们共同努力的结果。下面是参与翻译与校 对的朋友:-fil:*thanks.lua*-dsc:to print th list of th contributing guyshlpful_guys=”-参与番必译-“,HbuxiuT 凤舞影天,Hzhang3“morlr,Hlambdan,sunlight,nnn-参与校对-,“凤舞影天,Hdoylen,“flicker”,花生魔人,H zhang3 H r nkasicass n r nnn)for in ipairs(hIpful_guys)do print(e)nd 翻译组2005年7月26日注:本pdf为翻译稿,校对工作正在进行。Copyright 2005,Roberto lerusalimschy&Programming in Lua 出目录版权声明.i译序.i目录.iii第一篇语言.1第0章序言.10.1序言.10.2 Lua的使用者.20.3 Lua的相关资源.30.4本书的体例.30.5关于本书.30.6感谢.4第1章起点.51.1 Chunks.51.2 全局变量.71.3 词法约定.71.4 命令行方式.7第2章类型和值.92.1 Nil.92.2 Booleans.92.3 Numbers.102.4 Strings.102.5 Functions.122.6 Userdata and Threads.12第3章表达式.133.1 算术运算符.133.2 关系运算符.133.3 逻辑运算符.133.4 连接运算符.143.5 优先级.153.6 表的构造.15第4章基本语法.184.1 赋值语句.184.2 局部变量与代码块(block).194.3 控制结构语句.20Copyright 2005,Roberto lerusalimschy&Programming in Lua jv4.4 break 和 return 语句.23第5章函数.245.1 多返回值.255.2 可变参数.275.3 命名参数.28第6章再论函数.306.1 闭包.326.2 非全局函数.346.3 正确的尾调用(Proper Tail Calls).36第7章迭代器与泛型for.407.1 迭代器与闭包.407.2 范性for的语义.427.3 无状态的迭代器.437.4 多状态的迭代器.447.5 真正的迭代器.45第8章编译运行错误信息.478.1 require 函数.498.2 C Packages.508.3 错误.518.4 异常和错误处理.528.5 错误信息和回跟踪(Tracebacks).53第9章协同程序.569.1 协同的基础.569.2 管道和过滤器.589.3 用作迭代器的协同.619.4 非抢占式多线程.63第10章 完整示例.6810.1 Lua作为数据描述语言使用.6810.2 马尔可夫链算法.71第二篇 tables 与 objects.75第11章数据结构.7611.1 数组.7611.2 矩阵和多维数组.7711.3 链表.7811.4 队列和双端队列.7811.5 集合和包.8011.6 字符串缓冲.80第12章 数据文件与持久化.8412.1序列化.86Copyright 2005,Roberto lerusalimschy&Programming in Luav第 13 章 Metatables and Metamethods.9213.1 算术运算的 Metamethods.9213.2 关系运算的 Metamethods.9513.3 库定义的 Metamethods.9613.4 表相关的 Metamethods.97第14章环境.10314.1 使用动态名字访问全局变量.10314.2 声明全局变量.10414.3 非全局的环境.106第 15 章 Packages.10915.1 基本方法.10915.2 私有成员(Privacy).Ill15.3 包与文件.11215.4 使用全局表.11315.5 其他一些技巧(OtherFacilities).115第16章面向对象程序设计.11816.1 类.11916.2 继承.12116.3 多重继承.12216.4 私有性(privacy).12516.5 Single-Method的对象实现方法.127第 17 章 Weak 表.12817.1 记忆函数.13017.2 关联对象属性.13117.3 重述带有默认值的表.132第三篇标准库.134第18章数学库.135第 19 章 Table 库.13619.1 数组大小.13619.2 插入珊U除.13719.3 排序.137第 20 章 String 库.14020.1 模式匹配函数.14120.2 模式.14320.3 捕获(Captures).14620.4 转换的技巧(Tricks of the Trade).151第21章10库.15721.1 简单I/O模式.15721.2 完全I/O模式.160Copyright 2005,Roberto lerusalimschy&Programming in Lua vi第22章操作系统库.16522.1 Date 和 Time.16522.2 其它的系统调用.167第 23 章 Debug 库.16923.1 自省(Introspective).16923.2 Hooks.17323.3 Profiles.174第四篇CAPI.177第24章CAPI纵览.17824.1 第一个示例程序.17924.2 堆栈.18124.3 C API的错误处理.186第25章 扩展你的程序.18825.1 表操作.18925.2 调用Lua函数.19325.3 通用的函数调用.195第26章调用C函数.19826.1 C 函数.19826.2 C函数库.200第27章撰写C函数的技巧.20327.1 数组操作.20327.2 字符串处理.20427.3 在C函数中保存状态.207第 28 章 User-Defined Types in C.21228.1 Userdata.21228.2 Metatables.21528.3 访问面向对象的数据.21728.4 访问数组.21928.5 Light Userdata.220第29章资源管理.22229.1 目录迭代器.22229.2 XML 解析.225第四篇附录.234A.终端机控制符.235Copyright 2005,Roberto lerusalimschy&Programming in Lua1第一篇语言Copyright 2005,Roberto lerusalimschy&Programming in Lua1第0章序言本章包括作者的序言、文章的体例(convention)以及其它一些“每本书开头都会的 内容0.1序言目前很多程序语言都专注于帮你编写成千上万行的代码,所以此类型的语言所提供 的包、命名空间、复杂的类型系统及无数的结构,有上千页的文档需要操作者学习。而Lua并不帮你编写大量的代码的程序,相反的,Lua仅让你用少量的代码解决关 键问题。为实现这个目标,像其他语言一样Lua依赖于其可扩展性。但是与其他语常不 同的是,不仅用Lua编写的软件易于扩展,而且用其他语言比如C/C+编写的软件也很 容易使用Lua扩展其功能。一开始,Lua就被设计成很容易和传统的C/C+整合的语常。这种语言的二元性带 来了极大的好处。Lua是一个小巧而简单的语言,因为Lua不致力于做C语言已经做得 很好的领域,比如:性能、底层操作以及与第三方软件的接口。Lua依赖于C去做完成 这些任务。Lua所提供的机制是C不善于的:高级语言、动态结构、简洁、易于测试和 调试等。正因为如此,Lua具有良好的安全保证,自动内存管理,简便的字符串处理功 能及其他动态数据的改变。Lua不仅是一种易于扩展的语言,也是一种易整合语言(glue language);Lua支持 基于组件的,我们可以将一些已经存在的高级组件整合在一起实现一个应用软件。一般 情况下,组件使用像C/C+等静态的语言编写。但Lua是我们整合各个组件的粘合剂。又通常情况下,组件(或对象)表现为具体在程序开发过程中很少变化的、占用大量CPU 时间的决定性的程序,例如窗口部件和数据结构。对那种在产品的生命周期内变化比较 多的应用方向使用Lua可以更方便的适应变化。除了作为整合语言外,Lua自身也是一 个功能强大的语言。Lua不仅可以整合组件,还可以编辑组件甚至完全使用Lua创建组 件。除了 Lua外,还有很多类似的脚本语言,例如:Perl、Tel、Ruby、Forth Pythono 虽然其他语常在某些方面与Lua有着共同的特色,但下面这些特征是Lua特有的:可扩展性。Lua的扩展性非常卓越,以至于很多人把Lua用作搭建领域语言的:工具(注:比如游戏脚本)。Lua被设计为易于扩展的,可以通过Lua代码或者C 代码扩展,Lua的很多功能都是通过外部库来扩展的。Lua很容易与C/C+、java、fortran、Smalltalk Ada,以及其他语言接口。简单。Lua本身简单,小巧;内容少但功能强大,这使得Lua易于学习,很容 易实现一些小的应用。他的完全发布版(代码、手册以及某些平台的二进制文件)Copyright 2005,Roberto lerusalimschy&Programming in Lua 2仅用一张软盘就可以装得下。高效率。Lua有很高的执行效率,统计表明Lua是目前平均效率最高的脚本语 言。与平台无关。Lua几乎可以运行在所有我们听说过的系统上,如NextStep.0S/2 PlayStation II(Sony)Mac OS-9、OS X、BOS、MS-DOS、IBM mainframs、EPOC、PalmOS、MCF5206L工TE Evaluation Board、RISC OS,及所有的Windows和Unixo Lua不是通过使用条件编译实现平台无关,而 是完全使用ANSI(ISO)C,这意味着只要你有ANS工C编译器你就可以编译并:使用Luao:Lua大部分强大的功能来自于他的类库,这并非偶然。Lua的长处之一就是可以通 过新类型和函数来扩展其功能。动态类型检查最大限度允许多态出现,并自动简化调用 内存管理的接口,因为这样不需要关心谁来分配内存谁来释放内存,也不必担心数据溢 出。高级函数和匿名函数均可以接受高级参数,使函数更为通用。Lua自带一个小规模的类库。在受限系统中使用Lua,如嵌入式系统,我们可以有 选择地安装这些类库。若运行环境十分严格,我们甚至可以直接修改类库源代码,仅保 留需要的函数。记住:Lua是很小的(即使加上全部的标准库)并且在大部分系统下你 仍可以不用担心的使用全部的功能。0.2 Lua的使用者Lua使用者分为三大类:使用Lua嵌入到其他应用中的、独立使用Lua的、将Lua 和C混合使用的。第一:很多人使用Lua嵌入在应用程序,比如CGILua(搭建动态网页)、LuaOrb(访 问CORBA对象。这些类型用Lua-API注册新函数,创建新类型,通过配置Lua就可以 改变应用宿主语言的行为。通常,这种应用的使用者并不知道Lua是一种独立的语言。例如:CGILua用户一般会认为Lua是一种用于Web的语言。第二:作为一种独立运行的语言,Lua也是很有用的,主要用于文本处理或者只运 行一次的小程序。这种应用Lua主要使用它的标准库来实现,标准库提供模式匹配和其 它一些字串处理的功能。我们可以这样认为:Lua是文本处理领域的嵌入式语言。第三:还有一些使用者使用其他语言开发,把Lua当作库使用。这些人大多使用C 语言开发,但使用Lua建立简单灵活易于使用的接口。本书面向以上三类读者。书的第一部分阐述了语言的本身,展示语言的潜在功能。我们讲述了不同的语言结构,并用一些例子展示如何解决实际问题。这部分既包括基本 的语言的控制结构,也包括高级的迭代子和协同。第二部分重点放在Lua特有的数据结构一一tables上,讨论了数据结构、持久性、包 及面向对象编程,这里我们将看到Lua的真正强大之处。第三部分介绍标准库。每个标准库一章:数学库、table库、string库、I/O库、OS Copyright 2005,Roberto lerusalimschy&Programming in Lua 3库、Debug 库。最后一部分介绍了 Lua和C接口的API,这部分介绍在C语言中开发应用而不是 Lua中,应用对于那些打算将Lua嵌入到C/C+中的读者可能会对此部分更感兴趣。0.3 Lua的相关资源如果你真得想学一门语言,参考手册是必备的。本书和Lua参考手册互为补充,手 册仅仅描述语言本身,因此他既不会告诉你语言的数据结构也不会举例说明,但手册是 Lua的权威性文档,www.lua.org可以得到手册的内容。匚一;ua用户社区,鹿根亍二通备三十包和S当.1lua-us工s.org本书的更新勘误表,代码和例子;www.inf.puc-rio.br/robrto/book/:_I另外本书仅针对Lua 5.0,如果你的版本不同,请查阅Lua手册或者比较版本间的差 异。0.4本书的体例vl字符串使用双引号,比如literal strings;单字符使用单引号,比如区;模式串 也是用单引号,比如符号-表示语句的输出或者表达式的结果:;print(10)-10:13+3 16符号表示等价,即对于Lua来说,用this与that没有区别。:this that0.5关于本书开始打算写这本书是1998年冬天(南半球),那时候Lua版本是3.1;2000年v4.0;2003 年 v5.0o很明显的是,这些变化给本书带来很大的冲击,有些内容失去了它存在理由,比如 关于超值(upvalues)的复杂的解释。一些章节被重写,比如CAPL另外一些章节被增 加进来,比如协同处理。不太明显的是,Lua语言本身的发展对本书的完成也产生了很大的影响。一些语言 Copyright 2005,Roberto lerusalimschy&Programming in Lua 4的变化在本书中并没有被涵盖进来,这并非偶然的。在本书的创作过程中,有的时候在 某个章节我会突然感觉很困惑,因为我不知道该从何开始或者怎样去讲问题阐述清楚。当你想尽力去解释清楚如何使用的前提是你应该觉得使用这个东西很容易,这表明Lua 某些地方需要被改进。还有的时候,我顺利的写完某个章节,结果却是没有人能看得懂 我写的或者没有人对我在这个章节内表达的观点达成一致。大部分情况下,这是我的过 错因为我是个作家,偶尔我也会因此发现语言本身的一些需要改进的缺陷(举例来说,从upvalues到lexical scoping的转变是由无意义的尝试所带来的抱怨所弓I发的,在此书 的先前的草稿里,把upvalues形容成是lexical scoping的一种)。本书的完成必须服从语言的变化,本书在这个时候完成的原因:Lua 5.0是一个成熟的版本|语言变得越来越大,超出了最初本书的目标。此外一个原因是我迫切的想将|:Lua介绍给大家让更多的人了解Lua。0.6感谢在完成本书的过程中,很多人给了我极大的帮助:Luiz Henrique de Figueiredo和Waldemar Celes给了我很大的帮助,使得本书能够更 好完成,Luiz Henrique也帮助设计了本书的内部。Noemi Rodriguez,Andre Carregal,Diego Nehab,以及 Gavin Wraith 阅读了本书的草 稿提出了很多有价值的建议。Renato Cerqueira,Carlos Cassino,Tomds Guisasola,Joe Myers 和 Ed Ferguson 也提出 了很多重要的建议。Alexandre Nakonechnyj负责本书的封面和内部设计。Rosane Teles负责CIP数据的准备。谢谢他们所有人。Copyright 2005,Roberto lerusalimschy&Programming in Lua 5第1章起点写一个最最简单的程序Hello Worldoprint(Hallo World)假定你把上面这句保存在hello.lua文件中,你在命令行只需要:prompt lua hllo.lua看到结果了吗?让我们来看一个稍微复杂点的例子:clafinas a factorial function function fact(n)if n=0 thanrturn 1Is return n*fact(n-1)ndndprint(ntr a numbar:)a=io.rad(*numbr)一一 rad a numbarprint(fact(a)这个例子定义了一个函数,计算输入参数n的阶乘;本例要求用户输入一个数字n,然后打印n的阶乘。1.1 ChunksChunk是一系列语句,Lua执行的每一块语句,比如一个文件或者交互模式下的每 一行都是一个Chunko每个语句结尾的分号(;)是可选的,但如果同一行有多个语句最好用;分开a=1 b=a*2-ugly,but valid一个Chunk可以是一个语句,也可以是一系列语句的组合,还可以是函数,Chunk 可以很大,在Lua中几个MByte的Chunk是很常见的。你还可以以交互模式运行Lua,不带参数运行Lua:Copyright 2005,Roberto lerusalimschy&Programming in Lua 6Lua 5.0 Copyright 1994-2 003 Tcgraf,PUC-Rio 你键入的每个命令(比如:Hello World1)在你键入回车之后立即被执行,键入文 件结束符可以退出交互模式(Ctrl-D in Unix,Ctrl-Zin DOS/Windows),或者调用OS库 的os.exit。函数也可以退出。在交互模式下,Lua通常把每一个行当作一个Chunk,但如果Lua 一行不是一个完 整的Chunk时,他会等待继续输入直到得到一个完整的Chunk.在Lua等待续行时,显示 不同的提示符(一般是).可以通过指定参数让Lua执行一系列Chunk。例如:假定一个文件a内有单个语句 x=l;另一个文件b有语句print(x)prompt lua-la-lb命令首先在一个Chunk内先运行a然后运行b。(注意:-1选项会调用require,将会 在指定的目录下搜索文件,如果环境变量没有设好,上面的命令可能不能正确运行。我 们将在8.1节详细更详细的讨论the require function)-i选项要求Lua运行指定Chunk后进入交互模式.prompt lua-i la lb将在一个Chunk内先运行a然后运行b,最后直接进入交互模式。另一个连接外部Chunk的方式是使用dofile函数,dofile函数加载文件并执行它.假 设有一个文件:fillibl.luafunction norm(x,y)local n2=xA2+yA2 raturn math.sqrt(n2)nd在交互模式下:function twic(x)return 2*xnd dofil(“libl.lua”)-load your library n=norm(3.4,1.0)print(twic(n)7.0880180586677-i和dofile在调试或者测试Lua代码时是很方便的。Copyright 2005,Roberto lerusalimschy&Programming in Lua712全局变量全局变量不需要声明,给一个变量赋值后即创建了这个全局变量,访问一个没有初 始化的全局变量也不会出错,只不过得到的结果是:nil.如果你想删除一个全局变量,只需要将变量负值为nilprint(b)nilb=10print(b)10b=nilprint(b)nil这样变量b就好像从没被使用过一样.换句话说,当且仅当一个变量不等于nil时,这个变量存在。1.3词法约定标示符:字母(letter)或者下划线开头的字母、下划线、数字序列.最好不要使用下划 线加大写字母的标示符,因为Lua的保留字也是这样的。Lua中,letter的含义是依赖于 本地环境的。保留字:以下字符为Lua的保留字,不能当作标识符。:andbr akdoIsIsif:ndfalsaforfunctionifinlocalnilnotorrpatreturnthantruuntilJ:whil注意:Lua是大小写敏感的.注释:单行注释:-多行注释:-print(10)-no action(commnt)1.4命令行方式lua options script argsCopyright 2005,Roberto lerusalimschy&Programming in Lua 8-e:直接将命令传入Luaprompt lua 一 Hprint(math.sin(12)n-0.53657291800043-1:加载一个文件.-i:进入交互模式.,PROMPT内置变量作为交互模式的提示符prompt lua-i 一 H_PROMPT=,lua 1HluaLua的运行过程,在运行参数之前,Lua会查找环境变量LUAJNIT的值,如果变 量存在并且值为filename,Lua将加载指定文件。如果变量存在但不是以开头,Lua 假定file11ame为Lua代码文件并且运行他。利用这个特性,我们可以通过配置,灵活的 设置交互模式的环境。可以加载包,修改提示符和路径,定义自己的函数,修改或者重 命名函数等。全局变量arg存放Lua的命令行参数。prompt lua script a b c在运行以前,Lua使用所有参数构造arg表。脚本名索引为0,脚本的参数从1开始 增加。脚本前面的参数从-1开始减少。promptlua 一 Hsin=math.sinH script a barg表如下:arg-3=nluaHarg-2=厂”arg-1=n sin=math.sinnarg 0=H scriptnarg1=HaHarg2=HbHCopyright 2005,Roberto lerusalimschy&Programming in Lua9第2章类型和值Lua是动态类型语言,变量不要类型定义。Lua中有8个基本类型分别为:nil,boolean,number string、userdata function thread 和 table。函数 type 可以测试给定变量或者值 的类型。变量没有预定义的类型,每一个变量都可能包含任一种类型的值。print(typ(Hallo world)stringprint(typ(10.4*3)numbarprint(typ(print)functionprint(typ(typ)functionprint(typ(tru)boolanprint(typ(nil)nilprint(typ(typ(X)stringprint(typ(a)-nil(*a*is not initializd)a=10print(typ(a)numbara=Ha string!”print(typ(a)-stringa=printyas,this is valid!a(typ(a)-function注意上面最后两行,我们可以使用function像使用其他值一样使用(更多的介绍参 考第六章)。一般情况下同一变量代表不同类型的值会造成混乱,最好不要用,但是特殊 情况下可以带来便利,比如nil。2.1 NilLua中特殊的类型,他只有一个值:nil;一个全局变量没有被赋值以前默认值为nil;给全局变量负nil可以删除该变量。22 Booleans两个取值false和true。但要注意Lua中所有的值都可以作为条件。在控制结构的条 件中除了 false和nil为假,其他值都为真。所以Lua认为。和空串都是真。Copyright 2005,Roberto lerusalimschy&Programming in Lua 102.3 Numbers表示实数,Lua中没有整数。一般有个错误的看法CPU运算浮点数比整数慢。事实 不是如此,用实数代替整数不会有什么误差(除非数字大于lOOOOOQOOOOOOOO)。Lua 的numbers可以处理任何长整数不用担心误差。你也可以在编译Lua的时候使用长整型 或者单精度浮点型代替numbers,在一些平台硬件不支持浮点数的情况下这个特性是非 常有用的,具体的情况请参考Lua发布版所附的详细说明。和其他语言类似,数字常量 的小数部分和指数部分都是可选的,数字常量的例子:4 0.4 4.57e-3 0.3el2 5e+2024 Strings指字符的序列。lua是8位字节,所以字符串可以包含任何数值字符,包括嵌入的0。这意味着你可以存储任意的二进制数据在一个字符串里。Lua中字符串是不可以修改的,你可以创建一个新的变量存放你要的字符串,如下:a=on string”b=string.gsub(a,on,“anothr)-chang string partsprint(a)-on stringprint(b)-anothr stringstring和其他对象一样,Lua自动进行内存分配和释放,一个string可以只包含一个 字母也可以包含一本书,Lua可以高效的处理长字符串,1M的string在Lua中是很常见 的。可以使用单引号或者双引号表示字符串a=Ha lineHb=anothr lin为了风格统一,最好使用一种,除非两种引号嵌套情况。对于字符串中含有引号的 情况还可以使用转义符来表示。Lua中的转义序列有:aballbback spac一后退fform fd一换页nnwlin一换行rcarriage raturn回车thorizontal tab-制表vvrtical tabbackslash_ ndoubl quota双弓I号singl quota一单引号_JCopyright 2005,Roberto lerusalimschy&Programming in Lua;1 ft square bracket-左中括号:right square bracket-右中括号例子:print(on linnnxt linnin quotas,on linnxt【inn in quotas,*in quotas print(*a backslash insid quotas:*)1a backslash insid quotas:1!print(Ha simplr way:*n)1a simplr way:*1,in quotas 1n)还可以在字符串中使用ddd(ddd为三位十进制数字)方式表示字母。”alonl23”和 971o1004923”是相同的。还可以使用表示字符串。这种形式的字符串可以包含多行也,可以嵌套且不会 解释转义序列,如果第一个字符是换行符会被自动忽略掉。这种形式的字符串用来包含 一段代码是非常方便的。pag=An HTML PagLuaa txt btwn doubl bracketsJio.writ(pag)运行时,Lua会自动在string和numbers之间自动进行类型转换,当一个字符串使 用算术操作符时,string就会被转成数字。反过来,当Lua期望一个string而碰到数字时,会将数字转成stringoprint(n10 n+1)11print(H10+1”)10+1print(”-5.3-10”*H2H)-1.06-0 9print(”hllo”+1)-ERROR(cannot convert hallo)Copyright 2005,Roberto lerusalimschy&Programming in Lua 12print(10.20)-1020.在Lua中是字符串连接符,当在一个数字后面写.时,必须加上空格以防止被解释 错。尽管字符串和数字可以自动转换,但两者是不同的,像10=”10”这样的比较永远 都是错的。如果需要显式将string转成数字可以使用函数tonumber。,如果string不是正 确的数字该函数将返回nil。反之,可以调用tostring()将数字转成字符串,这种转换一直有效:lin=io.rad()-rad alinn=tonumbr(lin)if n=nil than-try toconvrt it to a numberrro工(lin.HIsprint(n*2)ndis not a validnumbar)print(tostring(lO)=10”)-truprint(10.nn=H10 H)tru2.5 Functions函数是第一类值(和其他变量相同),意味着函数可以存储在变量中,可以作为函数 的参数,也可以作为函数的返回值。这个特性给了语言很大的灵活性:一个程序可以重 新定义函数增加新的功能或者为了避免运行不可靠代码创建安全运行环境而隐藏函数,此外这特性在Lua实现面向对象中也起了重要作用(在第16章详细讲述)。Lua可以调用lua或者C实现的函数,Lua所有标准库都是用C实现的。标准库包 括string库、table库、I/O库、OS库、算术库、debug库。2.6 Userdata and Threadsuserdata可以将C数据存放在Lua变量中,userdata在Lua中除了赋值和相等比较外 没有预定义的操作。userdata用来描述应用程序或者使用C实现的库创建的新类型。例 如:用标准I/O库来描述文件。下面在C API章节中我们将详细讨论。在第九章讨论协同操作的时候,我们介绍线程。Copyright 2005,Roberto lerusalimschy&Programming in Lua第3章表达式Lua中的表达式包括数字常量、字符串常量、变量、一元和二元运算符、函数调用。还可以是非传统的函数定义和表构造。3.1算术运算符二元运算符:+-*/八(加减乘除暴)一元运算符:-(负值)这些运算符的操作数都是实数。32关系运算符:=这些操作符返回结果为false或者true;=和=比较两个值,如果两个值类型不同,Lua认为两者不同;nil只和自己相等。Lua通过引用比较tables、userdata functionso 也就是说当且仅当两者表示同一个对象时相等。a=;a.x=1;a.y=0b=;b.x=1;b.y=0c=aa=c but a-=bLua比较数字按传统的数字大小进行,比较字符串按字母的顺序进行,但是字母顺 序依赖于本地环境。当比较不同类型的值的时候要特别注意:n0n=0-falsa2 15-truH2H n15n-falsa(alphabtical ordr!)为了避免不一致的结果,混合比较数字和字符串,Lua会报错,比如:2 5print(nil and 13)-nilprint(falsa and 13)-falsaprint(4 or 5)-4print(falsa or 5)-5一个很实用的技巧:如果x为false或者nil则给x赋初始值vx=x or v等价于if not x thanX=Vndand的优先级比or高。C语言中的三元运算符 a?b:c在Lua中可以这样实现:(a and b)or cnot的结果只返回false或者trueprint(notnil)truprint(notfalsa)t ruprint(not0)falsaprint(notnot nil)falsa3.4连接运算符-两个点字符串连接,如果操作数为数字,Lua将数字转成字符串。Copyright 2005,Roberto lerusalimschy&Programming in Lua 15print(Hallo”.“World”)一 Hallo Worldprint(0.1)013.5优先级从高到低的顺序:not-(unary)*/+=andor除了人和.外所有的二元运算符都是左连接的。a+i b/2+1(a+i)(b/2)+l)5+xA2*85+(xA2)*8)a y and y=z(a y)and(y=z)-xA2-(x八2)xAyA zxA(yAz)3.6表的构造构造器是创建和初始化表的表达式。表是Lua特有的功能强大的东西。最简单的构 造函数是卜用来创建一个空表。可以直接初始化数组:days=Sunday,Monday,Tusday,HWednesdayH AH ThursdayH,nFridayH r H SaturdayHLua将Sunday”初始化daysl(第一个元素索引为1),用Monday”初始化daysprint(days4)-Wdnsday构造函数可以使用任何表达式初始化:tab=sin(1),sin(2),sin(3),sin(4),sin(5),sin(6),sin(7),sin(8)如果想初始化一个表作为record使用可以这样:a=x=0,y=0 a=;a.x=0;a.y=0Copyright 2005,Roberto lerusalimschy&Programming in Lua 16不管用何种方式创建table,我们都可以向表中添加或者删除任何类型的域,构造函 数仅仅影响表的初始化。w x0 r y0 rlabl=consol”x=sin(0),sin(1),sin(2)w1=anothrfiId”x.f=wprint(wnxH)0print(w1)-anoth工 fiIdprint(x.f 1)-anothr fiIdw.x=nil-ramova fiId HxH每次调用构造函数,Lua都会创建一个新的table,可以使用table构造一个list:list=nilfor lin in io.lins()do list=nxt=list,valu=linnd这段代码从标准输入读进每行,然后反序形成链表。下面的代码打印链表的内容:1=listwhil 1 doprint(1.valu)1=l.nxtnd在同一个构造函数中可以混合列表风格和record风格进行初始化,如:polylin=color=blu,thicknss=2,npoints=4,x=0,y=o,x=-10Ay=o,x=-10,y=i,x=0,y=i这个例子也表明我们可以嵌套构造函数来表示复杂的数据结构.print(polylin2.x)-10上面两种构造函数的初始化方式还有限制,比如你不能使用负索引初始化一个表中 元素,字符串索引也不能被恰当的表示。下面介绍一种更一般的初始化方式,我们用 expression显示的表示将被初始化的索引:opnams=+n=naddn,n-n=sub,=mul,/n =HdivH Copyright 2005,Roberto lerusalimschy&Programming in Lua 17i=20;s=n-na=i+0=sr i+1=s.s,i+2=s.s.sprint(opnamss)-subprint(a22)-list风格初始化和record风格初始化是这种一般初始化的特例:x=0,y=0 nx=0A Hy=0r cP,grn,blue l=Hred 2=Hgreen 3=nbluen如果真的想要数组下标从0开始:days=0=H SundayH,Monday,Tusday,Wdnsday”,n Thursdayn r Friday”,H SaturdayH注意:不推荐数组下标从0开始,否则很多标准库不能使用。在构造函数的最后的T是可选的,可以方便以后的扩展。a=1=H redH f 2=grn,3=blu”,在构造函数中域分隔符逗号可以用分号(”;)替代,通常我们使用分号用来 分割不同类型的表元素。x=l0,y=4 5;on,two,thr”Copyri
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传
相似文档                                   自信AI助手自信AI助手

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服