pr的lumetri(pr的lumetri)
and break do else elseif end false for function if in local nil not or repeat return then true until whileLua变量全局变量 - 所有变量都被视为全局变量,除非明确声明为局部变量。2boolean包括true和false作为值,通常用于条件检
and break do else elseif end false for function if in local nil not or repeat return then true until whileLua变量全局变量 - 所有变量都被视为全局变量,除非明确声明为局部变量。2boolean包括true和false作为值,通常用于条件检查。4string表示字符数组。5function表示用C语言或Lua编写的方法。6userdata表示任意C语言数据。7thread表示独立的执行线程,它用于实现协同程序。8table表示普通数组,符号表,集合,记录,图形,树等,并实现关联数组。#"Hello" 将返回 5Lua运算符优先级具有最高优先级的运算符显示在表的顶部,具有最低优先级的运算符显示在底部。当执行离开作用域时,将销毁在该作用域中创建的所有自动对象。Lua支持以下控制语句。while循环通常用于此目的。需要注意的是,在Lua中,零将被视为true。
Lua标识符是用于标识变量,函数或任何其他用户定义项的名称。 标识符以字母A到Z或a到z或下划线_开头,后跟零个或多个字母,下划线和数字(0到9)。 Lua不允许标识符中的标点符号,如@,$和%。 Lua是一种区分大小写的编程语言。 因此,Yiibai和yiibai是Lua中的两个不同的标识符。 以下是可接受标识符的一些示例 以下列表显示了Lua中的一些保留字。 这些保留字不能用作常量或变量或任何其他标识符名称。 编号 值类型 描述 1 nil 用于区分值与某些数据或没有(nil)数据。 2 boolean 包括true和false作为值,通常用于条件检查。 3 number 表示实数(双精度浮点)数字。 4 string 表示字符数组。 5 function 表示用C语言或Lua编写的方法。 6 userdata 表示任意C语言数据。 7 thread 表示独立的执行线程,它用于实现协同程序。 8 table 表示普通数组,符号表,集合,记录,图形,树等,并实现关联数组。 它可以保存任何值(除了nil)。 运算符 描述 示例 + 相加两个操作数 A + B = 30 - 从第一个减去第二个操作数 A - B = -10 * 将两个操作数相乘 A * B = 200 / 用除分子除以分子 B / A = 2 % 模数运算符,整数除法后的余数 B % A = 0 ^ 指数运算符取指数幂值 A^2 = 100 - 一元,充当否定 -A = -10 运算符 描述 示例 == 检查两个操作数的值是否相等,如果相等,则条件变为真。 (A == B)结果为false ~= 检查两个操作数的值是否相等,如果值不相等则条件变为true。 (A ~= B)结果为true > 检查左操作数的值是否大于右操作数的值,如果是,则条件变为true。 (A > B)结果为false < 检查左操作数的值是否小于右操作数的值,如果是,则条件变为true。 (A < B)结果为true >= 检查左操作数的值是否大于或等于右操作数的值,如果是,则条件变为true。 (A >= B)结果为false <= 检查左操作数的值是否小于或等于右操作数的值,如果是,则条件变为true。 (A <= B)结果为true 运算符 描述 示例 and 逻辑与运算符。如果两个操作数都不为零,则条件成立。 (A and B) 结果为false or 逻辑或运算符。 如果两个操作数中的任何一个不为零,则条件变为真。 (A or B) 结果为true not 逻辑非运算符。用于反转其操作数的逻辑状态。 如果条件为真,则逻辑非运算符将为false。 !(A and B)结果为true 编号 描述 示例 .. 连接两个字符串 如果a为Hello,b为World,a..b将返回Hello World。 # 返回字符串或表长度的一元运算符。 #"Hello" 将返回 5 具有最高优先级的运算符显示在表的顶部,具有最低优先级的运算符显示在底部。 在表达式中,将首先评估更高优先级的运算符。 类别 操作符 关联性 一元 not # - 右到左 连接 .. 右到左 乘法 * / % 左到右 加法 + - 左到右 关系 < > <= >= == ~= 左到右 相等 == ~= 左到右 逻辑与 and 左到右 逻辑或 or 左到右 Lua提供以下类型的循环来处理循环需求。 编号 循环类型 描述 1 while循环 在给定条件为真时重复语句或语句组,它在执行循环体之前测试条件。 while(condition) 2 for循环 多次执行一系列语句,并缩写管理循环变量的代码。 for init,max/min value, increment 3 repeat…unti循环 重复语句组的操作,直到满足until条件。 repeat 4 嵌套循环 可在任何循环中使用另一个或多个循环,如:while,for或do..while循环。 循环控制语句从正常顺序改变执行。 当执行离开作用域时,将销毁在该作用域中创建的所有自动对象。 Lua支持以下控制语句。 编号 控制语句 描述 1 break语句 终止循环并将执行转移到循环或switch之后的语句。 如果条件永远不会变为假,则循环变为无限循环。 while循环通常用于此目的。如果直接给出了一个条件为真,它就会永远执行。可以使用break语句来打断这个无限循环。 Lua编程语言假定布尔true和non-nil值的任意组合为true,如果它是布尔false或nil,则假定为false值。 需要注意的是,在Lua中,零将被视为true。 Lua编程语言提供以下类型的决策制定语句 - 编号 决策语句 描述 1 if语句 if语句由布尔表达式后跟一个或多个语句组成。 2 if…else语句 if语句后面可以跟一个可选的else语句,该语句在布尔表达式为false时执行。 3 嵌套if语句 在一个if或else if语句中使用另一个if或else if语句。 Lua编程语言中方法定义的一般形式如下 - Lua编程语言中的方法定义由方法头和方法体组成。以下是方法的所有部分 - 字符串是由一系列字符以及控制字符组成,如换页符。 字符串可以用三种形式初始化,包括 - 字符串中使用转义序列字符来更改字符的正常解释。例如,要打印双引号(""),在上面的示例中使用了"。转义序列及其用法列在下表中。 转义序列 用法 \a 铃 \b 退格 \f 换页 \n 新行 \r 回车 \t 制表符 \v 垂直制表符 \\ 反斜杠 " 双引号 ' 单引号 \[ 左方括号 \] 右方括号 Lua支持字符串来操作字符串 - 编号 方法 作用 1 string.upper(argument) 返回参数的大写表示。 2 string.lower(argument) 返回参数的小写表示。 3 string.gsub(mainString,findString,replaceString) 返回用replaceString替换findString后字符串。 4 string.find(mainString,findString, optionalStartIndex,optionalEndIndex) 返回mainString中findString的起始索引和结束索引找到字符串,如果未找到则返回nil。 5 string.reverse(arg) 将传递的字符串arg反转后的字符串。 6 string.format(...) 返回格式化字符串。 7 string.char(arg) 和 string.byte(arg) 返回输入参数的内部数字和字符表示。 8 string.len(arg) 返回传递字符串arg的长度。 9 string.rep(string, n)) 通过重复相同的字符串n次返回一个字符串。 10 .. 此运算符连接两个字符串。 数组是对象的有序排列,可以是包含行集合的一维数组或包含多个行和列的多维数组。 在Lua中,使用带整数的索引表实现数组。 数组的大小不固定,它可以根据要求增长,受内存限制。 迭代器泛型提供集合中每个元素的键值对。 下面给出一个简单的例子。 上面的例子使用了Lua提供的默认ipairs迭代器函数。 在Lua中,使用函数来表示迭代器。 基于这些迭代器函数中的状态维护,有两种主要类型 - 通过名称,可以理解这种类型的迭代器函数不会保留任何状态。下面来看一个使用打印n个数字的函数square创建迭代器的示例。 稍微修改上面的代码,以模仿迭代器的ipairs函数的工作方式。 如下代码所示 - 上面使用函数的迭代示例不保留状态。 每次调用该函数时,它都会根据发送给函数的第二个变量返回集合的下一个元素。 要保持当前元素的状态,可使用闭包(Closure)。 闭包在函数调用中保留变量值。 要创建一个新的闭包,这里首先创建两个函数,包括闭包本身和一个工厂,即创建闭包的函数。 现在来看看一个创建迭代器的例子,并将使用闭包。 当运行上面的程序时,将得到以下输出 - 在上面的例子中,可以看到elementIterator中有另一个方法,它使用局部外部变量index和count来通过每次调用函数时递增索引来返回集合中的每个元素。 可使用闭包创建函数迭代器,如上所示,它可以为迭代整个集合的每个时间返回多个元素。 表是Lua中唯一可用的数据结构,使用表可以创建不同的类型,如数组和字典。 Lua使用关联数组,不仅可使用数字编制索引,还可以使用除nil之外的字符串编制索引。 表没有固定的大小,可以根据需要增长大小。 Lua在所有表示中使用表,包括包的表示。 当访问方法string.format时,这意味着,访问字符串包中可用的格式函数。 表称为对象,它既不是值也不是变量。 Lua使用构造函数表达式{}来创建一个空表。 应该知道,保持表的引用的变量和表本身之间没有固定的关系。 假设有一个包含元素集的表a,如果将它分配给表b,则a和b都指向相同的内存。 Lua不会单独为b分配单独的内存。 当a设置为nil时,b仍然可以访问表。 当没有对表的引用时,Lua中的垃圾收集器负责清理进程以使这些未引用的内存再次被重用。 下面示出了一个例子,用于解释表的上述特征。 当运行上述程序时,将获得以下输出 - 下面是用于表操作的内置函数,它们列在下表格中。 编号 方法 作用 1 table.concat(table [, sep [, i [, j]]]) 根据给定的参数连接表中的字符串。详细信息请参见示例。 2 table.insert(table, [pos,] value) 在指定位置的表中插入值。 3 table.maxn(table) 返回最大的数字索引。 4 table.remove(table [, pos]) 从表中删除值。 5 table.sort(table [, comp]) 根据可选的比较器参数对表进行排序。 下面来看看一些上述功能的示例。 使用concat函数来连接两个表,如下所示 - 当运行上述程序时,将获得以下输出 - 在表操作中,最常见的是在表中插入和删除项目。如下解释。 当运行上述程序时,将获得以下输出 - 有时想要按特定顺序对表进行排序。 排序函数按字母顺序对表中的元素进行排序。 这方面的示例如下所示。 当运行上述程序时,将获得以下输出 - 模块是一个可以使用require加载的库,并且只有一个包含表的全局名称。 模块可以包含许多功能和变量。 所有这些函数和变量都包含在表中,表充当命名空间。 此外,一个良好的模块有必要的子句,以在使用require语句时返回此表。 模块中表的使用以多种方式,能够使用与操作任何其他Lua表相同的方式操作模块。 由于能够操作模块,它提供了其他语言需要特殊机制的额外功能。 由于Lua中模块的这种自由机制,用户可以通过多种方式调用Lua中的函数。 其中一些操作示例如下所示。 在上面的示例代码中,可以看到Lua中的编程灵活性,没有任何特殊的附加代码。 Lua提供了一个名为require的高级函数来加载所有必需的模块。 它保持尽可能简单,以避免有太多关于模块的信息来加载。 require函数只是将模块假定为一块代码,它定义了一些值,实际上是包含函数或表。 示例 考虑一个简单的例子,其中一个函数是数学函数。 将此模块称为mymath,文件名为mymath.lua。 文件的代码内容如下 - 现在,为了在另一个文件(例如,moduletutorial.lua)中访问此Lua模块,需要使用以下代码段。 要运行此代码,需要将两个Lua文件放在同一目录中,或者,可以将模块文件放在包路径(package.path)中,它需要额外的设置。 当运行上面的程序时,将得到以下输出 - 注意事项 下面将以旧方式重写上面相同的示例,它使用package.seeall类型的实现。 这在Lua版本5.1和5.0中使用。 mymath模块如下所示。 moduletutorial.lua 中模块的用法如下所示: 当运行上面的操作时,将获得相同的输出。 但建议使用较旧版本的代码,并假设它不太安全。 许多使用Lua进行编程的SDK如Corona SDK都不推荐使用它。 元表(metatable)是一个表,它是使用键集和相关元方法来修改附加到的表的行为。 这些元方法是强大的Lua功能,可实现如下功能 - 在处理元表时有两种重要的方法,包括 - 首先来看看如何将一个表设置为另一个表的元表。 如下所示 - 上面的代码可以用一行表示,如下所示 - 下表显示了元表在表中不可用时查找元表的示例。 当运行上面的程序时,将得到以下输出结果 - 下面来逐步看看上面例子中发生的事情。 上述程序的简化版本,如下所示 - 当将__newindex添加到metatable时,如果表中没有键,则新键的行为将由元方法定义。 下面给出了当主表中没有索引时设置metatable索引的简单示例。 运行上述程序时,将获得以下输出 - 在上面的程序中看到,如果主表中存在一个键,它只会更新它。 当维护中的键不可用时,它会将该键添加到metatable中。 使用rawset函数更新同一个表的另一个示例如下所示 - 当运行上面的程序时,将获得以下输出。 rawset设置值而不使用元表的__newindex。 类似地,有一个rawget可以在不使用__index的情况下获取值。 使用+运算符组合两个表的简单示例如下所示 - 当运行上面的程序时,将得到以下输出 - __add键包含在元表中以添加运算符 + 的行为。键表和相应的操作符如下所示。 编号 模式 描述 1 __add 改变运算符+的行为。 2 __sub 改变运算符-的行为。 3 __mul 改变运算符*的行为。 4 __div 改变运算符/的行为。 5 __mod 改变运算符%的行为。 6 __unm 改变运算符-的行为。 7 __concat 改变运算符..的行为。 8 __eq 改变运算符==的行为。 9 __lt 改变运算符<的行为。 10 __le 改变运算符<=的行为。 使用__call语句添加方法调用的行为。 一个简单的示例,它返回主表中的值与传递的表的总和。 当运行上面的程序时,将得到以下输出。 要更改print语句的行为,可以使用__tostring元方法。 一个简单的例子如下所示。 当运行上面的程序时,将得到以下输出。 如果完全了解元表的功能,那么可以真正执行很多非常复杂的操作。 因此,尝试使用元表中可用的不同选项的元表更多地工作。 协同程序本质上是协作的,它允许两种或多种方法以受控方式执行。 使用协同程序,在任何给定时间,只有一个协同程序运行,并且此运行协程仅在显式请求暂停时暂停执行。 上述定义可能看起来含糊不清。 假设有两种方法, 下表列出了Lua中协程的所有可用函数及其相应的用法。 编号 方法 作用或目的 1 coroutine.create (f) 使用函数f创建一个新的协同程序,并返回thread类型的对象。 2 coroutine.resume (co [, val1, ...]) 恢复协程co并传递参数(如果有的话)。它返回操作状态和可选的其他返回值。 3 coroutine.running () 如果在主线程中调用,则返回正在运行的协同程序或nil。 4 coroutine.status (co) 根据协同程序的状态返回running,normal,suspended或dead中的一个值。 5 coroutine.wrap (f) 与coroutine.create一样,coroutine.wrap函数也会创建一个协同程序,但它不会返回协同程序本身,而是返回一个函数,当调用它时,它会恢复协同程序。 6 coroutine.yield (...) 暂停正在运行的协同程序。 传递给此方法的参数充当resume函数的附加返回值。 示例 下面来看一个例子,通过此示例来理解协同程序的概念。 当运行上面的程序时,将得到以下输出 - 上面的例子是实现什么功能? 如前所述,使用resume函数来启动操作和yield函数来停止操作。 此外,可以看到coroutine的恢复功能接收到多个返回值。 下面来看一个简单的协同程序示例,它使用yield函数和resume函数返回1到5之间的数字。 如果不可用它会创建协程,或者恢复现有的协程。 当运行上面的程序时,将得到以下输出。 通常会将协同程序与多路程序设计语言的线程进行比较,但需要了解协同程序具有类似的线程功能,但协同程序一次只执行一个程序,并且永远不会同时执行。 通过暂时保留某些信息来控制程序执行顺序以满足需求。 使用带有协同程序的全局变量为协同程序提供了更大的灵活性。 I/O库用于读取和操作Lua中的文件。 Lua中有两种文件操作,即隐式文件描述符和显式文件描述符。 对于以下示例,将使用示例文件 - test.lua,内容如下所示 - 文件打开操作使用以下语句 - 下表列出了各种文件模式 - 编号 模式 描述 1 r 只读模式,是打开现有文件的默认模式。 2 w 写入启用模式,覆盖现有文件或创建新文件。 3 a 附加模式,用于打开现有文件或创建新文件以进行追加。 4 r+ 现有文件的读写模式。 5 w+ 如果文件存在或创建具有读写权限的新文件,则删除所有现有数据。 6 a+ 启用了读取模式的追加模式可打开现有文件或创建新文件。 隐式文件描述符使用标准输入/输出模式或使用单个输入和单个输出文件。 使用隐式文件描述符的示例如下所示。 运行程序时,将获得test.lua 文件第一行的输出。执行上面程序,得到以下输出 - 这是test.lua 文件中声明的第一行。 同时也将"-- End of the test.lua file"这一行附加到test.lua 文件中的最后一行。 在上面的示例中,可以使用io."x"方法查看隐式描述符如何与文件系统一起使用。 上面的示例使用不带可选参数的io.read()方法。可选参数可以是以面中的任何一个。 编号 模式 描述 1 *n 从当前文件位置读取并返回一个数字(如果存在于文件位置或返回nil)。 2 *a 从当前文件位置返回文件的所有内容。 3 *l 从当前文件位置读取行,并将文件位置移动到下一行。 4 number 读取函数中指定的字节数。 其他常见的I/O方法包括, 显式文件描述符经常使用,它允许一次操作多个文件。 这些函数与隐式文件描述符非常相似。 在这里,使用file:function_name,而不是io.function_name。 下面显示了以下相同隐式文件描述符示例的显式文件描述符版本示例。 运行程序时,将获得与隐式描述符示例类似的输出 - 文件打开的所有模式和用于读取外部描述符的参数与隐式文件描述符相同。 其他常见的文件方法包括, 使用搜索方法的示例如下所示。它将光标从文件结束前的25个位置偏移。 read函数从搜索位置打印文件的剩余部分。 执行上面示例代码,将获得类似于以下内容的输出 - 读者可自己使用所有的模式和参数来了解Lua文件操作的完整功能。 错误处理非常关键,因为实际操作通常需要使用复杂的操作,包括文件操作,数据库事务和Web服务调用。 在任何编程中,总是需要错误处理。 错误可以是两种类型,它们包括 - 由于不正确地使用各种程序组件(如运算符和表达式),从而发生语法错误。 语法错误的一个简单示例如下所示- 使用单个“单等于号”和“双等于号”之间存在差异。 使用不当可能导致错误。 一个“等于”指的是赋值,而两个“等于”指的是比较。 语法错误的另一个示例如下所示 - 当运行上述程序时,将获得以下输出 - 语法错误比运行时错误更容易处理,因为Lua解释器比运行时错误更清楚地定位错误。 从上面的错误中,可以很容易地知道根据Lua结构在print语句之前添加do语句。 如果出现运行时错误,程序将成功执行,但由于输入错误或错误处理的函数,可能会导致运行时错误。 显示运行时错误的简单示例如下所示。 当构建上面程序时,它将成功构建并运行。 运行后,显示运行时错误。 这是由于未传递两个参数变量而发生的运行时错误。 b参数是预期的,但是因为它未传入,默认使用的是nil从而产生错误。 要处理错误,经常使用两个函数是 - assert和error。 一个简单的例子如下所示。 当构建上面程序时,它将成功构建并运行。 运行后,显示运行时错误。 在Lua编程中,为了避免抛出这些错误和处理错误,需要使用pcall或xpcall函数。 pcall(f,arg1,...)函数在保护模式下调用所请求的函数。 如果函数f中发生某些错误,则不会抛出错误。 它只返回错误状态。 使用pcall的一个简单示例如下所示。 当构建上面程序时,它将成功构建并运行。 运行后,显示运行时错误。 xpcall(f,err)函数调用所请求的函数,并设置错误处理程序。 f内的任何错误都不会传播; 而xpcall只捕获错误,使用原始错误对象调用err函数,并返回状态代码。 xpcall函数的一个简单示例如下所示 - 当运行上面的程序时,将得到以下输出。 作为程序员,最重要的是确保在编写的程序中处理正确的错误处理。 使用错误处理可以确保处理超出边界条件的意外条件而不会干扰程序的用户。 Lua提供了一个调试库,它提供了创建自己的调试器的原始函数。 即使没有内置的Lua调试器,也有许多第三方Lua调试器,由各种开发人员创建,其中许多是开源的。 下表中列出了Lua调试库中可用的功能及其用法。 编号 方法 描述 1 debug() 进入用于调试的交互模式,该模式保持活动状态,直到用户只输入一行中的cont并按Enter键。 用户可以使用其他功能在此模式下检查变量。 2 getfenv(object) 返回对象的环境。 3 gethook(optional thread) 返回线程的当前挂钩设置,有三个值 - 当前挂钩函数,当前挂钩掩码和当前挂钩计数。 4 getinfo(optional thread, function or stack level, optional flag) 返回一个包含函数信息的表。可以直接给出函数,或者可以给一个数字作为函数的值,在给定线程的调用堆栈的级别函数上运行的函数 - 级别0为当前函数(getinfo本身); 级别1为调用getinfo的函数;等等。 如果function是一个大于活动函数数的数字,则getinfo返回nil。 5 getlocal(optional thread, stack level, local index) 6 getmetatable(value) 返回给定对象的元表,如果没有元表,则返回nil。 7 getregistry() 返回注册表表,这是一个预定义的表,任何C语言代码都可以使用它来存储它需要存储的任何Lua值。 8 getupvalue(function, upvalue index) 此函数返回upvalue的名称和值,索引为函数func。 如果给定索引没有upvalue,则函数返回nil。 9 setfenv(function or thread or userdata, environment table) 将给定对象的环境设置为给定表,返回对象。 10 sethook(optional thread, hook function, hook mask string with "c" and/or "r" and/or "l", optional instruction count) 将给定函数设置为钩子。 字符串掩码和数字计数描述了何时调用挂钩。 这里,每次Lua调用,返回并分别输入函数中的每一行代码时,都会调用c,r和l。 11 setlocal(optional thread, stack level, local index, value) 使用堆栈级别的函数的索引local将值赋给局部变量。 如果没有具有给定索引的局部变量,则该函数返回nil,并且当使用超出范围的级别调用时引发错误。 否则,它返回局部变量的名称。 12 setmetatable(value, metatable) 将给定对象的metatable设置为给定表(可以为nil)。 13 setupvalue(function, upvalue index, value) 此函数使用函数func的索引up将值赋给upvalue。 如果给定索引没有upvalue,则函数返回nil。 否则,它返回upvalue的名称。 14 traceback(optional thread, optional message string, optional level argument) 使用回溯构建扩展错误消息。 上面的列表是Lua中完整的调试函数列表,经常使用一个上述函数的库,并提供更简单的调试。 使用这些函数并创建我们自己的调试器非常复杂,并不是优选的。 下面来看一个简单使用调试功能的例子。 当运行上面的程序时,将获得如下所示的堆栈跟踪 - 在上面的示例程序中,使用调试库中提供的debug.trace函数打印堆栈跟踪。 debug.getinfo获取函数的当前表。 开发人员经常为了知道函数的局部变量以进行调试。 为此,可以使用getupvalue和使用setupvalue并设置这些局部变量。 一个简单的例子如下所示 - 当运行上面的程序时,将获得如下所示的堆栈跟踪 - 在此示例中,计数器每次调用时都会更新一次。 可以使用getupvalue函数查看局部变量的当前状态。 然后,将局部变量设置为新值。 这里,在调用set操作之前n为2。 使用setupvalue函数,它更新为10。现在当调用计数器函数时,它将返回11而不是3。 在Lua中,调试类型主要有两种 - 1. 命令行调试 命令行调试是使用命令和打印语句在命令行进行调试的调试类型。 Lua有许多命令行调试器,下面列出了一些。 2. 图形调试 在IDE下可以进行图形调试,在IDE中可为各种状态(如变量值,堆栈跟踪和其他相关信息)进行可视化调试。 借助断点,步入,步进和IDE中的其他按钮,可以实现可视化表示和逐步控制执行。 Lua有许多图形调试器,它包括以下内容- Lua使用自动内存管理,该管理使用基于Lua内置的某些算法的垃圾收集。自动内存管理收集,作为开发人员 - Lua使用垃圾收集器它在后台会时不时地运行,收集和销毁Lua程序访问的死对象。 包括表,用户数据,函数,线程,字符串等在内的所有对象都需要进行自动内存管理。 Lua使用增量标记和扫描收集器,它使用两个数字来控制其垃圾收集周期,即垃圾收集器暂停和垃圾收集器步骤倍增器。 这些值以百分比表示,值100通常在内部等于1。 垃圾收集器暂停用于控制垃圾收集器之前需要等待多长时间; Lua的自动内存管理再次调用。 小于100的值意味着Lua不会等待下一个周期。 类似地,该值的较高值将导致垃圾收集器缓慢。 200的值表示收集器在开始新循环之前等待使用的总内存加倍。 因此,根据应用程序的性质和速度,可能需要更改此值以在Lua应用程序中获得最佳性能。 此步骤乘数控制垃圾收集器与Lua程序中内存分配的相对速度。 较大的步长值将导致垃圾收集器更具侵略性,并且还会增加垃圾收集的每个增量步骤的步长。 小于100的值通常可以避免垃圾收集器不完成循环并且通常不是优选的。 默认值为200,这意味着垃圾收集器的运行速度是内存分配的两倍。 作为开发人员,确实可以控制Lua中的自动内存管理。有以下方法可以使用。 使用垃圾收集器示例如下所示。 当运行上面的程序时,将得到以下输出。 请注意,由于操作系统类型的不同以及Lua的自动内存管理功能,此结果会有所不同。 在上面的程序中看到,完成垃圾收集,它就减少了使用的内存。 但是,这并不是强制要求。 即使不调用它们,它也会在预定义的时间段后由Lua解释器在稍后阶段自动执行。 显然,如果需要,可以使用这些函数来改变垃圾收集器的行为。 这些函数为开发人员提供了一些额外的功能来处理复杂的情况。 根据程序所需的内存类型,也可能不会使用此功能。 但了解应用程序中的内存使用情况并在编程期间检查它以避免在部署后出现意外结果非常有用。 面向对象编程(OOP)是现代编程中使用最多的编程技术之一。 有许多支持OOP的编程语言包括 - 可使用Lua的表和第一类函数在Lua中实现面向对象。 通过将函数和相关数据放入表中,形成对象。可使用元表实现继承,为父对象中不存在的函数(方法)和字段提供查找机制。 Lua中的表具有状态和标识等对象的特征,与其值无关。 具有相同值的两个对象(表)是不同的对象,而对象在不同的时间可以具有不同的值,但它始终是相同的对象。 与对象一样,表的生命周期与谁创建它们或创建位置无关。 面向对象的概念广泛使用,但需要清楚地理解面向对象以获得适当和最大的好处。 考虑一个简单的数学例子。 我们经常遇到处理不同形状的情况,如圆形,矩形和方形。 形状可以具有共同的属性area。 因此,使用公共属性区域从基础对象形状扩展其他形状。 每个形状都可以有自己的属性,像矩形这样的函数可以具有属性length,width,area作为属性,printArea和calculateArea作为它的函数。 下面显示了具有三个属性length,width和area的矩形的简单类实现。 它还有一个printArea函数来打印计算区域面积。 创建一个对象 创建对象是为类实例分配内存的过程。 每个对象都有自己的内存并共享公共类数据。 访问属性 可以使用点(.)运算符访问类中的属性,如下所示 - 访问成员函数 使用带有对象的冒号(:)运算符访问成员函数,如下所示 - 分配内存并设置初始值。可以将初始化过程与其他面向对象语言中的构造函数进行比较。 它只是一个能够设置如上所示的值的函数。 完整的例子 下面来看一下在Lua中使用面向对象的完整示例。代码如下 - 运行上述程序时,将获得以下输出 - 继承是将简单的基础对象(如形状)扩展为矩形,正方形等的过程。 它经常在现实世界中用于共享和扩展基本属性和功能。 下面来看一个简单的类扩展。有一个如下所示的类, 可以将形状扩展为方形类,如下所示。 覆盖基类函数 可以覆盖基类函数而不是在基类中使用函数,派生类可以有自己的实现,如下所示 - 继承完整示例 在另一个new方法的帮助下,使用metatables,扩展Lua中的简单类实现,如上所示。 基类的所有成员变量和函数都保留在派生类中。 当运行上述程序时,将获得以下输出 - 在上面的例子中,创建了两个派生类 - 基类Square和Rectangle。并在派生类中覆盖基类的函数。 在此示例中,派生类会覆盖函数printArea。 Lua是一种高度灵活的语言,通常用于多种平台,包括Web应用程序。 开普勒(Kepler)社区成立于2004年,旨在为Lua提供开源Web组件。 尽管已经有很多Lua Web开发是使用Lua的Web框架,但这里主要介绍和使用Kepler社区提供的组件。 Lua常用应用程序和框架 在本教程中,将让您了解Lua可以执行的操作,并了解有关其安装和使用的更多信息,请参阅kepler网站。 Orbit是Lua的MVC Web框架。 它完全放弃了CGILua“脚本”模型,转而支持应用程序,每个Orbit应用程序都可以放在一个文件中,但如果需要,可以将它分成多个文件。 所有Orbit应用程序都遵循WSAPI协议,因此它们目前与Xavante,CGI和Fastcgi一起使用。 它包含一个启动程序,可以轻松启动Xavante实例进行开发。 安装Orbit的最简单方法是使用LuaRocks。 Luarocks是安装Orbit的安装的命令。 为此,需要先安装LuaRocks。 如果尚未安装所有依赖项,则以下是在Unix/Linux 环境中设置Orbit时要遵循的步骤。 安装Apache 连接到服务器,使用以下命令安装Apache2及其支持模块并启用所需的Apache2模块 - 安装LuaRocks 安装WSAPI,FCGI,Orbit和Xavante 设置Apache2 在配置文件的<Directory /var/www/>部分下面添加以下部分。 如果此部分有AllowOverride None,则需要将None更改为All,以便.htaccess文件可以在本地覆盖配置。 重新启动服务器以确保所做的更改生效。 要启用应用程序,需要将+ExecCGI添加到Orbit应用程序根目录中的.htaccess文件中 - 在本例中目录为/var/www。 Orbit简单示例 - 现在,可以启动Web浏览器了。 转到http://localhost:8080/,应该看到以下输出 - Orbit提供了另一种选择,即Lua代码可以生成html。 创建表单 一个简单的表单示例,如下所示 - 如前所述,WSAPI充当许多项目的基础,并在其中嵌入了多个功能。 可以使用WSAPI并支持以下平台 - WSAPI支持的服务器和接口包括 - WSAPI提供了许多库,可以更轻松地使用Lua进行Web编程。 Lua中的一些受支持的功能包括, WSAPI的一个简单示例,如下所示 - 在上面的代码中看到形成并返回一个简单的html 页面。可以看到协同程序的用法,它可以将语句返回到调用函数。 最后,返回html状态代码(200),标题和html页面。 Xavante是一个Lua HTTP 1.1 Web服务器,它使用基于URI映射处理程序的模块化体系结构。 Xavante目前提供以下功能 - 文件处理程序用于常规文件。重定向处理程序启用URI重映射和WSAPI处理程序,以便与WSAPI应用程序一起处理。 一个简单的例子,如下所示 - 要使用Xavante的虚拟主机,对xavante.HTTP的调用将更改为如下所示 - 有许多基于Lua的Web框架和组件可供使用,根据需要选择它。 还有其他可用的Web框架,包括以下内容 - 这些Web框架可在Web应用程序中充分利用,以执行强大的操作功能。 对于简单的数据操作,可使用文件处理。但有时,这些文件操作可能效率不高,可扩展且功能强大。 为此经常需要使用数据库。 LuaSQL是一个从Lua到许多数据库管理系统的简单接口。 LuaSQL是一个库,它为不同类型的SQL提供支持。 包括 - 在本教程中,将介绍在Lua中如何使用MySQL和SQLite数据库操作处理。它为两者使用通用接口,并且也可以将此实现移植到其他类型的数据库。 首先来看看如何在MySQL中进行操作。 要使以下示例按预期工作,需要初始数据库安装设置。 假设如下 - 假设Lua实现正确完成,使用一个简单的require语句来导入sqlite库。 mysql = require "luasql.mysql" 变量mysql将通过引用主mysql表来提供对函数的访问。 通过启动MySQL环境,然后为环境创建连接。 如下所示 - 上述连接将连接到现有的MySQL文件,并与新创建的文件建立连接。 连接提供了一个简单的执行函数,可以帮助我们执行创建,插入,删除,更新等操作完成所有数据库操作。 语法如下所示 - 在上面的语法中,需要确保conn是打开的,以及MySQL连接成功,并用正确的SQL语句替换'MySQLSTATEMENT'。 创建表示例 下面显示了一个简单的create table示例。 它创建一个表,其中包含两个字段参数: id类型为integer,name类型为varchar。 运行上述程序时,将创建一个名为sample的表,其中包含两列,即id和name。 如果语句有任何错误,将返回错误语句而不是nil。 一个简单的错误声明如下所示 - 插入语句示例 MySQL的insert语句如下所示- 更新语句示例 MySQL的更新语句如下所示 - 删除语句示例 MySQL的删除语句如下所示 - 选择语句示例 就select语句而言,我们需要循环遍历每一行并提取所需的数据。一个简单的选择语句如下所示 - 在上面的代码中,conn是一个打开的MySQL连接。 在execute语句返回的游标的帮助下,可以遍历表响应并获取所需的选择数据。 下面给出了包括所有上述语句的完整示例 - 运行上述程序时,将获得以下输出 - 事务是一种确保数据一致性的机制。事务具有以下四个属性 - 事务以START TRANSACTION开始; 并以commit或rollback语句结束。 开始事务 要启动事务,需要在Lua中执行以下语句,假设conn是一个打开的MySQL连接。 回滚事务 需要执行以下语句来回滚执行启动事务后所做的更改。 提交事务 需要执行以下语句来提交启动事务执行后所做的更改。 在上面和后面的章节中已经了解了MySQL的基本SQL操作。 记住事务,虽然这里没有为SQLite3解释,但同样的语句也适用于SQLite3。 Lua由于其简单的语言结构和语法,它广泛地用于游戏引擎开发中。 垃圾收集功能通常在由于使用丰富的图形而消耗大量内存的游戏中非常有用。 一些使用Lua的游戏引擎包括 - 这些游戏引擎中的每一个都基于Lua,并且每个引擎中都有一组丰富的API。 接下来将简要介绍每种引擎功能。 Corona SDK是一款支持iPhone,iPad和Android平台的跨平台移动游戏引擎。 有一个免费版本的Corona SDK,可用于功能有限的小游戏。可以在需要时升级到其他版本。 Corona SDK提供了许多功能,包括以下功能 - 使用上述API开发应用程序比使用iOS和Android单独使用本机API更容易,更快捷。 Gideros提供跨平台SDK来为iOS和Android创建游戏,可以免费使用Gideros。 Gideoros的一些显着优势包括 - ShiVa3D是3D游戏引擎之一,它提供了一个图形编辑器,旨在为Web,控制台和移动设备创建应用程序和视频游戏。 它支持多种平台,包括Windows,Mac,Linux,iOS,Android,BlackBerry,Palm OS,Wii和WebOS。 一些主要功能包括 - Shiva3d的网络版是完全免费的,其他版本可能需要收费。 Moai SDK是一款支持iPhone,iPad和Android平台的跨平台移动游戏引擎。 Moai平台最初由Moai SDK(一种开源游戏引擎)和Moai Cloud(一种用于托管和部署游戏服务的服务的云平台)组成。 现在Moai Cloud已关闭,只有游戏引擎可用。 Moai SDK可在多种平台上运行,包括iOS,Android,Chrome,Windows,Mac和Linux。 LOVE是一个可用于制作2D游戏的框架,它是免费和开源的。 它支持Windows,Mac OS X和Linux平台。 它提供了多种功能,包括: CryEngine是由德国游戏开发商Crytek开发的游戏引擎。 它已从第1代发展到第4代,是一种先进的开发解决方案。 它支持PC,Xbox 360,PlayStation3和WiiU游戏。 它提供了多种功能,包括: 这些游戏SDK/框架中的每一个都有各自的优缺点。 在它们之间进行适当的选择可以让工作更轻松,并且可以更好地利用它。 因此,在使用它之前,需要了解游戏的要求,然后分析哪些能满足需求,然后才能决定使用哪一个。 Lua标准库提供了一组丰富的函数,这些函数直接使用C语言API实现,并使用Lua编程语言构建。这些库提供Lua编程语言中的服务以及文件和数据库操作之外的服务。 这些在官方C语言API中构建的标准库作为单独的C模块提供。它包括以下内容 - 我们在整个教程中使用了各种主题下的基本库。 下表提供了相关页面的链接,并列出了本Lua教程各部分所涵盖的功能。 编号 库/方法 作用 1 错误处理 包括错误处理函数,如断言, 错误,如Lua错误处理中所述。 2 内存管理 包括与垃圾收集相关的自动内存管理功能, 如Lua垃圾收集中所述。 3 dofile ([filename]) 它打开文件并以块的形式执行文件的内容。 4 _G 因此是保存全局环境的全局变量(即_G._G = _G)。 5 getfenv ([f]) 返回函数使用的当前环境。 6 getmetatable (object) 如果object没有metatable, 则返回nil。 否则,如果object的metatable具有__metatable字段, 7 ipairs (t) 此函数获取表的索引和值。 8 load (func [, chunkname]) 使用函数func加载一个块来获取它的碎片。 9 loadfile ([filename])) 与load类似,但是如果没有给出文件名,则从文件filename或标准输入中获取块。 10 loadstring (string [, chunkname]) 与load函数类似,但从给定的字符串中获取块。 11 next (table [, index]) 允许程序遍历表的所有字段。 12 pairs (t) 暂停正在运行的协同程序。 13 print (...) 打印给定的参数值。 14 rawequal (v1, v2) 检查v1是否等于v2,而不调用任何无方法。 返回一个布尔值。 15 rawget (table, index) 获取table [index]的值, 而不调用任何方法。table必须是表; index可以是任何值。 16 rawset (table, index, value) 将table [index]的值设置为value,而不调用任何方法。 17 select (index, ...) 如果index是数字,则返回参数编号索引后的所有参数。 18 setfenv (f, table) 设置给定函数使用的环境。 19 setmetatable (table, metatable) 设置给定表的元表。 20 tonumber (e [, base]) 尝试将参数转换为数字。 21 tostring (e) 接收任何类型的参数并将其转换为合理格式的字符串。 22 type (v) 返回唯一参数的类型,编码为字符串。 23 unpack (list [, i [, j]]) 返回给定表中的元素。 24 _VERSION 包含当前解释器版本的字符串的全局变量(不是函数)。 25 协同程序 包括Lua协同程序中解释的协程操作功能。 模块库提供了在Lua中加载模块的基本功能。 它直接在全局环境中导出一个函数:require。 其他所有内容都在表包中导出。 有关模块库的详细信息,请参见前面的Lua模块教程。 Lua提供了丰富的字符串操作功能。 前面的Lua字符串教程详细中介绍了这一点。 Lua几乎在其所有操作中都依赖于表。 前面的Lua表教程详中细介绍了这一点。 经常需要编程中的数据存储工具,这是由Lua中的文件I/O的标准库函数提供的。 它在前面的Lua 文件操作教程中讨论过。 Lua提供了一个调试库,它提供了创建自己的调试器的所有原始函数。 在前面的Lua调试教程中讨论过了。 经常需要在科学和工程计算中进行数学运算,可以使用标准的Lua库数学来实现。 数学库中可用的函数列表如下表所示 - 编号 库或方法 描述 1 math.abs(x) 返回x的绝对值。 2 math.acos(x) 返回x的弧余弦值(以弧度表示)。 3 math.asin(x) 返回x的弧正弦(以弧度表示)。 4 math.atan(x) 返回x的反正切(以弧度表示)。 5 math.atan2(y,x) 返回y / x的反正切(以弧度表示),但使用两个参数的符号来查找结果的象限(它也正确处理x为零的情况。) 6 math.ceil(x) 返回大于或等于x的最小整数。 7 math.cos(x) 返回x的余弦值(假设为弧度)。 8 math.cosh(x) 返回x的双曲余弦值。 9 math.deg(x) 以度为单位返回角度x(以弧度表示)。 10 math.exp(x) 返回值e的x次幂。 11 math.floor(x) 返回小于或等于x的最大整数。 12 math.fmod(x,y) 返回x除以y的余数,将商舍入为零。 13 math.frexp(x) 返回m和e,使得x = m2e,e是整数,m的绝对值在[0.5,1]范围内(或者当x为零时为零)。 14 math.huge HUGE_VAL值是一个大于或等于任何其他数值的值。 15 math.ldexp(m, e) 返回m2e(e是一个整数)。 16 math.log(x) 返回x的自然对数。 17 math.log10(x) 返回x的以10为底的对数。 18 math.max(x,...) 返回参数中的最大值。 19 math.min(x,...) 返回参数中的最小值。 20 math.modf(x) 返回两个数字,x的整数部分和x的小数部分。 21 math.pi pi的值。 22 math.pow(x,y) 返回x的y方。(也可以使用表达式x ^ y来计算此值。) 23 math.rad(x) 以弧度为单位返回角度x(以度为单位)。 24 math.random([m [, n]]) 此函数是ANSI C提供的简单伪随机生成器函数rand的接口。 25 math.randomseed(x) 将x设置为伪随机生成器的“种子”:相等的种子产生相等的数字序列。 26 math.sin(x) 返回x的正弦值(假设为弧度)。 27 math.sinh(x) 返回x的双曲正弦值。 28 math.sqrt(x) 返回x的平方根。(也可以使用表达式x ^ 0.5来计算此值。) 29 math.tan(x) 返回x的正切(假设为弧度)。 30 math.tanh(x) 返回x的双曲正切值。 使用三角函数的简单示例如下所示- 当运行上面的程序时,将得到以下输出 - 使用常见数学函数的简单示例如下所示- 当运行上面的程序时,将得到以下输出 - 上面的例子只是一些常见的例子,可以根据需要使用数学库,所以尝试使用所有的函数以更熟悉运用。 在任何应用程序中,通常都需要访问操作系统级功能,并且可以使用操作系统库。 可用功能列表如下表所示。 编号 库或方法 描述 1 os.clock() 返回程序使用的CPU时间(以秒为单位)的近似值。 2 os.date([format[, time]]) 返回包含日期和时间的字符串或表,根据给定的字符串格式进行格式化。 3 os.difftime(t2,t1) 返回从时间t1到时间t2的秒数。在POSIX,Windows和其他一些系统中,恰好是t2-t1的值。 4 os.execute([command]) 此功能相当于ANSI C功能系统。 它传递要由操作系统shell执行的命令。 如果命令成功终止,则第一个结果为true,否则为nil。 5 os.exit([code[, close]) 调用ANSI C函数出口以终止宿主程序。 如果code为true,则返回状态为EXIT_SUCCESS; 如果code为false,则返回状态为EXIT_FAILURE; 如果code是数字,则返回的状态是此数字。 6 os.getenv(varname) 返回进程环境变量varname的值,如果未定义变量,则返回nil。 7 os.remove(filename) 使用给定名称删除文件(或POSIX系统上的空目录)。 如果此函数失败,则返回nil,以及描述错误和错误代码的字符串。 8 os.rename(oldname, newname) 将名为oldname的文件或目录重命名为newname。 如果此函数失败,则返回nil,以及描述错误和错误代码的字符串。 9 os.setlocale(locale [,category]) 设置程序的当前区域设置。 locale是一个依赖于系统的字符串,用于指定语言环境; category是一个可选字符串,用于描述要更改的类别:all,collate,ctype,currency,numeric或time; 默认类别(category)是"all"。该函数返回新语言环境的名称,如果无法满足请求,则返回nil。 10 os.time([table]) 返回不带参数调用的当前时间,或表示给定表指定的日期和时间的时间。 此表必须包含字段年,月和日,并且可能包含字段小时(默认值为12),分钟(默认值为0),秒(默认值为0)和isdst(默认值为nil)。 有关这些字段的说明,请参见os.date函数。 11 os.tmpname() 返回一个文件名,该文件名可用于临时文件。 文件必须在使用前显式打开,并在不再需要时显式删除。 使用常见数学函数的简单示例如下所示 - 当运行上面的程序时,将得到类似的输出如下 - 上面的例子只是一些常见的例子,可根据自己的需要使用OS库,建议尝试使用所有的功能以便更加熟悉。像remove这样的函数有助于删除文件,执行有助于于执行OS命令。 http://stevedonovan.github.io/ldoc/manual/doc.md.html LDoc遵循JavaDoc等文档生成工具的传统,即只有doc comment可以被解析,这种doc comment必须以三个-开头Lua之参考
Lua注释
---- 注释--这是 lua 的单行注释--[[这是 lua 的多行注释第二行第三行--]]--[[这是 lua 的多行注释第二行第三行]]
Lua交互模式(lua -i)
> io.write("Hello world, from ",_VERSION,"!\n")Hello world, from Lua 5.4!file (0x7fff889b2ee8)> v=1> print(type(v));number> print(type(vv));nil> -- 20分配给变量g,30分配给变量l > g,l = 20,30-- type> print(type("What is my type")) --> stringstring> t = 10> print(type(5.8*t)) --> numbernumber> print(type(true)) --> booleanboolean> print(type(print)) --> functionfunction> print(type(nil)) --> nilnil> print(type(type(ABC))) --> stringstring
Lua标识符
mohd zara abc move_name a_123myname50 _temp j a23b9 retVal
Lua关键字
and break do else elseif end false for function if in local nil not or repeat return then true until while
Lua变量
Lua数据类型
Lua运算符
算术运算符
关系运算符
逻辑运算符
其它运算符
Lua运算符优先级
Lua循环
do
statement(s)
end
do
statement(s)
end
statement(s)
until( condition )循环控制声明
无限循环
while( true )doprint("This loop will run forever.")end
Lua决策结构
Lua函数
optional_function_scope function function_name( argument1, argument2, argument3........, argumentn) function_bodyreturn result_params_comma_separatedend
Lua字符串
string1 = "Lua"print("\"String 1 is\"",string1)string2 = 'Yiibai Tutorial'print("String 2 is",string2)string3 = [["Lua Tutorial"]]print("String 3 is",string3)
字符串操作
Lua数组
一维数组
array = {"Lua", "Tutorial"}for i = 0, 2 do print(array[i])end
多维数组
-- 初始化数组array = {}for i=1,3 do array[i] = {} for j=1,3 do array[i][j] = i*j endend-- 访问数组for i=1,3 do for j=1,3 do print(array[i][j]) endend
Lua迭代器
迭代器泛型
array = {"Lua", "Tutorial"}for key,value in ipairs(array) do print(key, value)end
无状态迭代器
function square(iteratorMaxCount,currentNumber) if currentNumber<iteratorMaxCount then currentNumber = currentNumber+1 return currentNumber, currentNumber*currentNumber endendfor i,n in square,3,0do print(i,n)end
function square(iteratorMaxCount,currentNumber) if currentNumber<iteratorMaxCount then currentNumber = currentNumber+1 return currentNumber, currentNumber*currentNumber endendfunction squares(iteratorMaxCount) return square,iteratorMaxCount,0end for i,n in squares(3)do print(i,n)end
有状态迭代器
array = {"Lua", "Tutorial"}function elementIterator (collection) local index = 0 local count = #collection -- The closure function is returned return function () index = index + 1 if index <= count then -- return the current element of the iterator return collection[index] end endendfor element in elementIterator(array)do print(element)end
LuaTutorial
Lua表
表示和用法
--sample table initializationmytable = {}--simple table value assignmentmytable[1]= "Lua"--removing referencemytable = nil-- lua garbage collection will take care of releasing memory
-- Simple empty tablemytable = {}print("Type of mytable is ",type(mytable))mytable[1]= "Lua"mytable["wow"] = "Tutorial"print("mytable Element at index 1 is ", mytable[1])print("mytable Element at index wow is ", mytable["wow"])-- alternatetable and mytable refers to same tablealternatetable = mytableprint("alternatetable Element at index 1 is ", alternatetable[1])print("mytable Element at index wow is ", alternatetable["wow"])alternatetable["wow"] = "I changed it"print("mytable Element at index wow is ", mytable["wow"])-- only variable released and and not tablealternatetable = nilprint("alternatetable is ", alternatetable)-- mytable is still accessibleprint("mytable Element at index wow is ", mytable["wow"])mytable = nilprint("mytable is ", mytable)
Type of mytable is tablemytable Element at index 1 is Luamytable Element at index wow is Tutorialalternatetable Element at index 1 is Luamytable Element at index wow is Tutorialmytable Element at index wow is I changed italternatetable is nilmytable Element at index wow is I changed itmytable is nil
表操作
1. 表连接
fruits = {"banana","orange","apple"}-- returns concatenated string of tableprint("Concatenated string ",table.concat(fruits))--concatenate with a characterprint("Concatenated string ",table.concat(fruits,", "))--concatenate fruits based on indexprint("Concatenated string ",table.concat(fruits,", ", 2,3))
Concatenated string bananaorangeappleConcatenated string banana, orange, appleConcatenated string orange, apple
2. 插入和删除
fruits = {"banana","orange","apple"}-- insert a fruit at the endtable.insert(fruits,"mango")print("Fruit at index 4 is ",fruits[4])--insert fruit at index 2table.insert(fruits,2,"grapes")print("Fruit at index 2 is ",fruits[2])print("Fruit at index 2 is ",table.concat(fruits,", ") )-- banana, orange, apple, mango --> banana, grapes, orange, apple, mangoprint("The maximum elements in table is",#fruits)--print("The maximum elements in table is",table.maxn(fruits))print("The last element is",fruits[5])table.remove(fruits)print("The previous last element is",fruits[5])
Fruit at index 4 is mangoFruit at index 2 is grapesThe maximum elements in table is 5The last element is mangoThe previous last element is nil
3. 排序表
fruits = {"banana","orange","apple","grapes"}for k,v in ipairs(fruits) do print(k,v)endtable.sort(fruits)print("sorted table")for k,v in ipairs(fruits) do print(k,v)end
1 banana2 orange3 apple4 grapessorted table1 apple2 banana3 grapes4 orange
Lua模块
Lua模块的特色
-- Assuming we have a module printFormatter-- Also printFormatter has a funtion simpleFormat(arg)-- Method 1require "printFormatter"printFormatter.simpleFormat("test")-- Method 2local formatter = require "printFormatter"formatter.simpleFormat("test")-- Method 3require "printFormatter"local formatterFunction = printFormatter.simpleFormatformatterFunction("test")
require函数
local mymath = {}function mymath.add(a,b) print(a+b)endfunction mymath.sub(a,b) print(a-b)endfunction mymath.mul(a,b) print(a*b)endfunction mymath.div(a,b) print(a/b)endreturn mymath
package.path = '/Users/fei/work/lua_work/learn/mymath.lua'mymathmodule = require("mymath")mymathmodule.add(10,20)mymathmodule.sub(30,20)mymathmodule.mul(10,20)mymathmodule.div(30,20)
30102001.5
实现模块的旧方法
module("mymath", package.seeall)function mymath.add(a,b) print(a+b)endfunction mymath.sub(a,b) print(a-b)endfunction mymath.mul(a,b) print(a*b)endfunction mymath.div(a,b) print(a/b)end
require("mymath")mymath.add(10,20)mymath.sub(30,20)mymath.mul(10,20)mymath.div(30,20)
Lua元表
mytable = {}mymetatable = {}setmetatable(mytable,mymetatable)getmetatable(mytable)
mytable = setmetatable({},{})getmetatable(mytable)
部分元方法介绍
__index -- 'table[key]',取下标操作,用于访问表中的域__newindex -- 'table[key] = value',赋值操作,增改表中的域__call -- 'func(args)',函数调用,(参见 《Lua 学习笔记(三)—— 表达式》中的函数部分介绍)-- 数学运算操作符__add -- '+'__sub -- '-'__mul -- '*'__div -- '/'__mod -- '%'__pow -- '^'__unm -- '-'-- 连接操作符__concat -- '..'-- 取长操作符__len -- '#'-- 比较操作符__eq -- '=='__lt -- '<' -- a > b 等价于 b < a__le -- '<=' -- a >= b 等价于 b <= a ## 参考: https://blog.csdn.net/yangzhenzhen/article/details/51233548
__index
mytable = setmetatable({key1 = "value1"}, { __index = function(mytable, key) if key == "key2" then return "metatablevalue" else return mytable[key] end end})print(mytable.key1,mytable.key2)
value1 metatablevalue
mytable = setmetatable({key1 = "value1"},{ __index = { key2 = "metatablevalue" } })print(mytable.key1,mytable.key2)
__newindex
mymetatable = {}mytable = setmetatable({key1 = "value1"}, { __newindex = mymetatable })print(mytable.key1)mytable.newkey = "new value 2"print(mytable.newkey,mymetatable.newkey)mytable.key1 = "new value 1"print(mytable.key1,mymetatable.newkey1)
value1nil new value 2new value 1 nil
mytable = setmetatable({key1 = "value1"}, { __newindex = function(mytable, key, value) rawset(mytable, key, "\""..value.."\"")end})mytable.key1 = "new value"mytable.key2 = 4print(mytable.key1,mytable.key2)
new value "4"
向表中添加运算符行为
mytable = setmetatable({ 1, 2, 3 }, { __add = function(mytable, newtable) for i = 1, (#newtable) do table.insert(mytable, (#mytable)+1,newtable[i]) end return mytable end})secondtable = {4,5,6}mytable = mytable + secondtableprint(table.concat(mytable," , "))for k,v in ipairs(mytable) do print(k,v)end
1 , 2 , 3 , 4 , 5 , 61 12 23 34 45 56 6
__call
mytable = setmetatable({10}, { __call = function(mytable, newtable) sum = 0 for i = 1, (#mytable) do sum = sum + mytable[i] end for i = 1, (#newtable) do sum = sum + newtable[i] end return sum end})newtable = {10,20,30}print(mytable(newtable))
70
__tostring
mytable = setmetatable({ 10, 20, 30 }, { __tostring = function(mytable) sum = 0 for k, v in pairs(mytable) do sum = sum + v end return "The sum of values in the table is " .. sum end})print(mytable)
The sum of values in the table is 60Shell
Lua协同程序 ??
一种是主程序方法,另一种是协程。 当使用resume函数调用一个协程时,它会开始执行,当调用yield函数时,它会暂停执行。
同样的协同程序可以继续执行另一个恢复函数调用,协同程序就会暂停。 该过程可以持续到协程执行结束。协同程序函数
co = coroutine.create(function (value1,value2) local tempvar3 = 10 print("coroutine section 1", value1, value2, tempvar3) local tempvar1 = coroutine.yield(value1+1,value2+1) tempvar3 = tempvar3 + value1 print("coroutine section 2",tempvar1 ,tempvar2, tempvar3) local tempvar1, tempvar2= coroutine.yield(value1+value2, value1-value2) tempvar3 = tempvar3 + value1 print("coroutine section 3",tempvar1,tempvar2, tempvar3) return value2, "end"end)print("main", coroutine.resume(co, 3, 2))print("main", coroutine.resume(co, 12,14))print("main", coroutine.resume(co, 5, 6))print("main", coroutine.resume(co, 10, 20))
coroutine section 1 3 2 10main true 4 3coroutine section 2 12 nil 13main true 5 1coroutine section 3 5 6 16main true 2 endmain false cannot resume dead coroutineShell
另一个协同程序示例
function getNumber() local function getNumberHelper() co = coroutine.create(function () coroutine.yield(1) coroutine.yield(2) coroutine.yield(3) coroutine.yield(4) coroutine.yield(5) end) return co end if(numberHelper) then status, number = coroutine.resume(numberHelper); if coroutine.status(numberHelper) == "dead" then numberHelper = getNumberHelper() status, number = coroutine.resume(numberHelper); end return number else numberHelper = getNumberHelper() status, number = coroutine.resume(numberHelper); return number endendfor index = 1, 10 doprint(index, getNumber())end
1 12 23 34 45 56 17 28 39 410 5
Lua文件操作
-- sample test.lua-- sample2 test.lua
file = io.open (filename [, mode])
1. 隐式文件描述符
-- Opens a file in readfile = io.open("test.lua", "r")-- sets the default input file as test.luaio.input(file)-- prints the first line of the fileprint(io.read())-- closes the open fileio.close(file)-- Opens a file in append modefile = io.open("test.lua", "a")-- sets the default output file as test.luaio.output(file)-- appends a word test to the last line of the fileio.write("-- End of the test.lua file\n")-- closes the open fileio.close(file)
-- Sample test.lua
2. 显式文件描述符
-- Opens a file in read modefile = io.open("test.lua", "r")-- prints the first line of the fileprint(file:read())-- closes the opened filefile:close()-- Opens a file in append modefile = io.open("test.lua", "a")-- appends a word test to the last line of the filefile:write("--test")-- closes the open filefile:close()
-- Sample test.lua
-- Opens a file in readfile = io.open("test.lua", "r")file:seek("end",-25)print(file:read("*a"))-- closes the opened filefile:close()
sample2 test.lua--test
Lua错误处理
1. 语法错误
a == 2
for a= 1,10 print(a)end
lua: test2.lua:2: 'do' expected near 'print'
2. 运行时错误
function add(a,b)return a+bendadd(10)
lua: test2.lua:2: attempt to perform arithmetic on local 'b' (a nil value)stack traceback:test2.lua:2: in function 'add'test2.lua:5: in main chunk[C]: ?
断言和错误功能
local function add(a,b) assert(type(a) == "number", "a is not a number") assert(type(b) == "number", "b is not a number") return a+bendadd(10)
lua: test2.lua:3: b is not a numberstack traceback:[C]: in function 'assert'test2.lua:3: in function 'add'test2.lua:6: in main chunk[C]: ?error(message [,level])终止最后一个调用的受保护函数,并将消息作为错误消息返回。 此函数错误永远不会返回。 通常,错误会在消息开头添加有关错误位置的一些信息。 level参数指定如何获取错误位置。 对于级别1(默认值),错误位置是调用错误函数的位置。 级别2将错误指向调用调用错误的函数的位置等等。 传递0级可避免向消息添加错误位置信息。
pcall和xpcall
function myfunction() n = n/nilendif pcall(myfunction) then print("Success")else print("Failure")end
Failure
function myfunction () n = n/nilendfunction myerrorhandler( err ) print( "ERROR:", err )endstatus = xpcall( myfunction, myerrorhandler )print( status)
ERROR: test2.lua:2: attempt to perform arithmetic on global 'n' (a nil value)false
Lua调试 ??
function myfunction () print(debug.traceback("Stack trace")) print(debug.getinfo(1)) print("Stack trace end") return 10endmyfunction ()print(debug.getinfo(1))
Stack tracestack traceback:test2.lua:2: in function 'myfunction'test2.lua:8: in main chunk[C]: ?table: 0054C6C8Stack trace end
调试示例
function newCounter () local n = 0 local k = 0 return function () k = n n = n + 1 return n endendcounter = newCounter ()print(counter())print(counter())local i = 1repeatname, val = debug.getupvalue(counter, i) if name then print ("index", i, name, "=", val) if(name == "n") then debug.setupvalue (counter,2,10) end i = i + 1 end -- ifuntil not nameprint(counter())
12index 1 k = 1index 2 n = 211
调试类型
Lua垃圾收集
垃圾收集器暂停
垃圾收集器步骤乘数
垃圾收集器函数
mytable = {"apple", "orange", "banana"}print(collectgarbage("count"))mytable = nilprint(collectgarbage("count"))print(collectgarbage("collect"))print(collectgarbage("count"))
22.59960937520.79296875021.5537109375
Lua面向对象编程
面向对象的特点
Lua面向对象
真实世界的例子
创建一个简单的类
-- Meta classRectangle = {area = 0, length = 0, breadth = 0}-- Derived class method newfunction Rectangle:new (o,length,breadth) o = o or {} setmetatable(o, self) self.__index = self self.length = length or 0 self.breadth = breadth or 0 self.area = length*breadth; return oend-- Derived class method printAreafunction Rectangle:printArea () print("The area of Rectangle is ",self.area)end
r = Rectangle:new(nil,10,20)
print(r.length)
r = Rectangle:new(nil,10,20)r:printArea()
-- Meta classShape = {area = 0}-- Base class method newfunction Shape:new (o,side) o = o or {} setmetatable(o, self) self.__index = self side = side or 0 self.area = side*side; return oend-- Base class method printAreafunction Shape:printArea ()print("The area is ",self.area)end-- Creating an objectmyshape = Shape:new(nil,10)myshape:printArea()
The area is 100
Lua继承
-- 元类Shape = {area = 0}-- 基类方法function Shape:new (o,side)o = o or {} setmetatable(o, self) self.__index = self side = side or 0 self.area = side*side; return oend-- 基类方法 - printAreafunction Shape:printArea ()print("The area is ",self.area)end
Square = Shape:new()-- Derived class method newfunction Square:new(o,side) o = o or Shape:new(o,side) setmetatable(o, self) self.__index = self return oend
-- Derived class method printAreafunction Square:printArea () print("The area of square is ",self.area)end
-- Meta classShape = {area = 0}-- Base class method newfunction Shape:new (o,side) o = o or {} setmetatable(o, self) self.__index = self side = side or 0 self.area = side*side; return oend-- Base class method printAreafunction Shape:printArea ()print("The area is ",self.area)end-- Creating an objectmyshape = Shape:new(nil,10)myshape:printArea()Square = Shape:new()-- Derived class method newfunction Square:new (o,side) o = o or Shape:new(o,side) setmetatable(o, self) self.__index = self return oend-- Derived class method printAreafunction Square:printArea ()print("The area of square is ",self.area)end-- Creating an objectmysquare = Square:new(nil,10)mysquare:printArea()Rectangle = Shape:new()-- Derived class method newfunction Rectangle:new (o,length,breadth) o = o or Shape:new(o) setmetatable(o, self) self.__index = self self.area = length * breadth return oend-- Derived class method printAreafunction Rectangle:printArea ()print("The area of Rectangle is ",self.area)end-- Creating an objectmyrectangle = Rectangle:new(nil,10,20)myrectangle:printArea()
The area is 100The area of square is 100The area of Rectangle is 200
Lua Web编程
Orbit
$ sudo apt-get install apache2 libapache2-mod-fcgid libfcgi-dev build-essential$ sudo a2enmod rewrite$ sudo a2enmod fcgid$ sudo /etc/init.d/apache2 force-reload
$ sudo apt-get install luarocks
$ sudo luarocks install orbit$ sudo luarocks install wsapi-xavante$ sudo luarocks install wsapi-fcgi
$ sudo raj /etc/apache2/sites-available/default
<IfModule mod_fcgid.c> AddHandler fcgid-script .lua AddHandler fcgid-script .ws AddHandler fcgid-script .op FCGIWrapper "/usr/local/bin/wsapi.fcgi" .ws FCGIWrapper "/usr/local/bin/wsapi.fcgi" .lua FCGIWrapper "/usr/local/bin/op.fcgi" .op #FCGIServer "/usr/local/bin/wsapi.fcgi" -idle-timeout 60 -processes 1 #IdleTimeout 60 #ProcessLifeTime 60</IfModule>
Options +ExecCGIDirectoryIndex index.ws
#!/usr/bin/env index.lua-- index.luarequire"orbit"-- declarationmodule("myorbit", package.seeall, orbit.new)-- handlerfunction index(web)return my_home_page()end-- dispatchmyorbit:dispatch_get(index, "/", "/index")-- Sample pagefunction my_home_page()end
First Page
#!/usr/bin/env index.lua-- index.luarequire"orbit"function generate()return html {head{title "HTML Example"},body{h2{"Here we go again!"}}}endorbit.htmlify(generate)print(generate())
#!/usr/bin/env index.luarequire"orbit"function wrap (inner)return html{ head(), body(inner) }endfunction test () return wrap(form (H'table' { tr{td"First name",td( input{type = 'text', name='first'})}, tr{td"Second name",td(input{type = 'text', name='second'})}, tr{ td(input{type = 'submit', value = 'Submit!'}), td(input{type = 'submit',value = 'Cancel'}) }, }))endorbit.htmlify(wrap,test)print(test())
WSAPI
#!/usr/bin/env wsapi.cgimodule(..., package.seeall)function run(wsapi_env) local headers = { ["Content-type"] = "text/html" } local function hello_text() coroutine.yield("<html><body>") coroutine.yield("<p>Hello Wsapi - by yiibai.com !</p>") coroutine.yield("<p>PATH_INFO: " .. wsapi_env.PATH_INFO .. "</p>") coroutine.yield("<p>SCRIPT_NAME: " .. wsapi_env.SCRIPT_NAME .. "</p>") coroutine.yield("</body></html>")end return 200, headers, coroutine.wrap(hello_text)end
Xavante
require "xavante.filehandler"require "xavante.cgiluahandler"require "xavante.redirecthandler"-- Define here where Xavante HTTP documents scripts are locatedlocal webDir = XAVANTE_WEBlocal simplerules = { { -- URI remapping example match = "^[^%./]*/#34;, with = xavante.redirecthandler, params = {"index.lp"} }, { -- cgiluahandler example match = {"%.lp#34;, "%.lp/.*#34;, "%.lua#34;, "%.lua/.*#34; }, with = xavante.cgiluahandler.makeHandler (webDir) }, { -- filehandler example match = ".", with = xavante.filehandler, params = {baseDir = webDir} }, } xavante.HTTP{server = {host = "*", port = 8080}, defaultHost = {rules = simplerules},}
xavante.HTTP{server = {host = "*", port = 8080},defaultHost = {},virtualhosts = {["www.yiibai.com"] = simplerules}}
Lua的Web组件
结束说明
Lua MySQL操作
MySQL数据库安装设置
导入MySQL
设置连接
local env = mysql.mysql()local conn = env:connect('test','root','123456')
执行函数
conn:execute([[ 'MySQLSTATEMENT' ]])
mysql = require "luasql.mysql"local env = mysql.mysql()local conn = env:connect('test','root','123456')print(env,conn)status,errorString = conn:execute([[CREATE TABLE sample2 (id INTEGER, name TEXT);]])print(status,errorString )
MySQL environment (004BB178) MySQL connection (004BE3C8)0 nil
LuaSQL: Error executing query. MySQL: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"id INTEGER, name TEXT)' at line 1
conn:execute([[INSERT INTO sample values('11','Maxsu')]])
conn:execute([[UPDATE sample3 SET name='Yiibai' where id ='12']])
conn:execute([[DELETE from sample3 where id ='12']])
cursor,errorString = conn:execute([[select * from sample]])row = cursor:fetch ({}, "a")while row do print(string.format("Id: %s, Name: %s", row.id, row.name)) -- reusing the table of results row = cursor:fetch (row, "a")end
一个完整的例子
mysql = require "luasql.mysql"local env = mysql.mysql()local conn = env:connect('test','root','123456')print(env,conn)status,errorString = conn:execute([[CREATE TABLE sample3 (id INTEGER, name TEXT)]])print(status,errorString )status,errorString = conn:execute([[INSERT INTO sample3 values('12','Maxsu')]])print(status,errorString )cursor,errorString = conn:execute([[select * from sample3]])print(cursor,errorString)row = cursor:fetch ({}, "a")while row do print(string.format("Id: %s, Name: %s", row.id, row.name)) row = cursor:fetch (row, "a")end-- close everythingcursor:close()conn:close()env:close()
MySQL environment (0037B178) MySQL connection (0037EBA8)0 nil1 nilMySQL cursor (003778A8) nilId: 12, Name: Maxsu
执行事务
conn:execute([[START TRANSACTION;]])
conn:execute([[ROLLBACK;]])
conn:execute([[COMMIT;]])
Lua游戏编程
1. Corona SDK
2. Gideros Mobile
3. ShiVa3D
4. Moai SDK
5. LOVE
6. CryEngine
Lua标准库
1. 基础库
2. 模块库
3. 字符串操作
4. 表操作
5. 文件输入和输出
6. 调试工具
Lua数学库
三角函数
radianVal = math.rad(math.pi / 2)io.write(radianVal,"\n")-- Sin value of 90(math.pi / 2) degreesio.write(string.format("%.1f ", math.sin(radianVal)),"\n")-- Cos value of 90(math.pi / 2) degreesio.write(string.format("%.1f ", math.cos(radianVal)),"\n")-- Tan value of 90(math.pi / 2) degreesio.write(string.format("%.1f ", math.tan(radianVal)),"\n")-- Cosh value of 90(math.pi / 2) degreesio.write(string.format("%.1f ", math.cosh(radianVal)),"\n")-- Pi Value in degreesio.write(math.deg(math.pi),"\n")
0.0274155677808040.0 1.0 0.0 1.0 180
其他常见的数学函数
-- Floorio.write("Floor of 10.5055 is ", math.floor(10.5055),"\n")-- Ceilio.write("Ceil of 10.5055 is ", math.ceil(10.5055),"\n")-- Square rootio.write("Square root of 16 is ",math.sqrt(16),"\n")-- Powerio.write("10 power 2 is ",math.pow(10,2),"\n")io.write("100 power 0.5 is ",math.pow(100,0.5),"\n")-- Absoluteio.write("Absolute value of -10 is ",math.abs(-10),"\n")--Randommath.randomseed(os.time())io.write("Random number between 1 and 100 is ",math.random(),"\n")--Random between 1 to 100io.write("Random number between 1 and 100 is ",math.random(1,100),"\n")--Maxio.write("Maximum in the input array is ",math.max(1,100,101,99,999),"\n")--Minio.write("Minimum in the input array is ",math.min(1,100,101,99,999),"\n")
Floor of 10.5055 is 10Ceil of 10.5055 is 11Square root of 16 is 410 power 2 is 100100 power 0.5 is 10Absolute value of -10 is 10Random number between 1 and 100 is 0.22876674703207Random number between 1 and 100 is 7Maximum in the input array is 999Minimum in the input array is 1
Lua操作系统工具
常见的OS功能
-- Date with formatio.write("The date is ", os.date("%m/%d/%Y"),"\n")-- Date and timeio.write("The date and time is ", os.date(),"\n")-- Timeio.write("The OS time is ", os.time(),"\n")-- Wait for some timefor i=1,1000000 doend-- Time since Lua startedio.write("Lua started before ", os.clock(),"\n")
The date is 01/25/2018The date and time is 01/25/18 07:38:40The OS time is 1490615720Lua started before 0.013
ldoc
参考
LDOC 入门指南 -- 重点是里面的安装 - ZhYQ_note - 博客园说明
安装方法
brew install luarocks -vluarocks install Ldoc
使用方法
> vim config.ldproject='ldoc_demo'title='一个用于测试LDoc的项目'description='一个用于测试LDoc的项目'file='.'> ldoc -v ldoc_demo