lua 5.3 英文手册 google机器翻译版

LUA Lua 5.3参考手册
作者:Roberto Ierusalimschy,Luiz Henrique de Figueiredo,Waldemar Celes

版权所有©2015-2018 Lua.org,PUC-Rio。根据Lua许可条款免费提供 。

内容 · 索引 · 其他版本
1 - 简介
Lua是一种功能强大,高效,轻量级,可嵌入的脚本语言。它支持过程编程,面向对象编程,函数编程,数据驱动编程和数据描述。

Lua将简单的过程语法与基于关联数组和可扩展语义的强大数据描述结构相结合。Lua是动态类型的,通过使用基于寄存器的虚拟机解释字节码来运行,并具有增量垃圾收集的自动内存管理,使其成为配置,脚本和快速原型设计的理想选择。

Lua实现为一个库,用干净的C编写,这是标准C和C ++的通用子集。Lua发行版包括一个名为的主机程序lua,它使用Lua库提供完整的独立Lua解释器,用于交互式或批量使用。Lua旨在用作任何需要的程序的强大,轻量级,可嵌入的脚本语言,以及作为一种功能强大但轻量级且高效的独立语言。

作为一种扩展语言,Lua没有“主要”程序的概念:它嵌入在主机客户端中,称为嵌入程序或简称主机。(通常,这个主机是独立的lua程序。)主机程序可以调用函数来执行一段Lua代码,可以编写和读取Lua变量,并且可以注册要由Lua代码调用的C函数。通过使用C函数,可以扩展Lua以应对各种不同的域,从而创建共享语法框架的定制编程语言。

Lua是免费软件,按照许可证的规定,照常提供,不提供担保。Lua的官方网站上提供了本手册中描述的实现www.lua.org。

与任何其他参考手册一样,本文档在某些地方是干燥的。有关Lua设计背后的决策的讨论,请参阅Lua网站上提供的技术论文。有关Lua编程的详细介绍,请参阅Roberto的书“ Lua编程”。

2 - 基本概念
本节介绍该语言的基本概念。

2.1 - 价值观和类型
Lua是一种动态类型语言。这意味着变量没有类型; 只有价值观。该语言中没有类型定义。所有值都有自己的类型。

Lua中的所有值都是一等值。这意味着所有值都可以存储在变量中,作为参数传递给其他函数,并作为结果返回。

Lua中有八种基本类型: nil,boolean,number, string,function,userdata, thread和table。nil类型只有一个值nil,其主要属性与任何其他值不同; 它通常代表缺乏有用的价值。boolean类型有两个值,false和true。两个零和假赚了条件为假; 任何其他价值都是真的。该类型的号码表示整数和实数(浮点)数。类型字符串表示不可变的字节序列。Lua是8位干净的:字符串可以包含任何8位值,包括嵌入的零(' \0')。Lua也是编码不可知的; 它没有假设字符串的内容。

类型号使用两个内部表示,或两个子类型,一个称为整数,另一个称为float。Lua有关于何时使用每个表示的明确规则,但它也会根据需要自动转换它们(参见§3.4.3)。因此,程序员可以选择主要忽略整数和浮点数之间的差异,或者假设完全控制每个数字的表示。标准Lua使用64位整数和双精度(64位)浮点数,但您也可以编译Lua,以便它使用32位整数和/或单精度(32位)浮点数。对于小型机器和嵌入式系统,整数和浮点数的32位选项特别有吸引力。(见宏LUA_32BITS在文件中luaconf.h。)

Lua可以调用(和操作)用Lua编写的函数和用C编写的函数(参见§3.4.10)。两者都由类型函数表示。

提供 类型userdata以允许任意C数据存储在Lua变量中。userdata值表示原始内存块。有两种用户数据: 完整用户数据,一个由Lua管理的内存块的对象,以及轻用户数据,它只是一个C指针值。除了赋值和身份测试之外,Userdata在Lua中没有预定义的操作。通过使用元表,程序员可以定义完整用户数据值的操作(参见§2.4)。只能通过C API在Lua中创建或修改Userdata值。这保证了主机程序拥有的数据的完整性。

类型线程表示独立的执行线程,它用于实现协同程序(参见§2.6)。Lua线程与操作系统线程无关。Lua支持所有系统上的协同程序,甚至是那些本身不支持线程的协同程序。

类型表实现关联数组,即不仅可以包含数字作为索引的数组,还可以包含除nil和NaN 之外的任何Lua值。(非数字是用于表示未定义或不可表示的数值结果的特殊值,例如0/0。)表可以是异构的 ; 也就是说,它们可以包含所有类型的值(除了nil)。值为nil的任何键都不被视为表的一部分。相反,任何不属于表的键都具有关联值nil。

表是Lua中唯一的数据结构机制; 它们可用于表示普通数组,列表,符号表,集合,记录,图形,树等。为了表示记录,Lua使用字段名称作为索引。该语言通过提供a.name语法糖来支持这种表示a["name"]。有几种方便的方法可以在Lua中创建表(参见§3.4.9)。

与索引一样,表字段的值可以是任何类型。特别是,因为函数是第一类值,所以表字段可以包含函数。因此,表格也可以带有方法(见§3.4.11)。

表的索引遵循语言中原始相等的定义。表达式a[i]和a[j] 表示相同的表元素当且仅当i和j原始相等(即,没有元方法时相等)。特别是,具有整数值的浮点数等于它们各自的整数(例如1.0 == 1)。为避免歧义,任何具有用作键的整数值的浮点数都将转换为其各自的整数。例如,如果你写a[2.0] = true,插入表中的实际键将是整数2。(另一方面,2和“ 2”是不同的Lua值,因此表示不同的表条目。)

表,函数,线程和(完整)用户数据值是对象:变量实际上不包含这些值,只是对它们的引用。赋值,参数传递和函数返回总是操纵对这些值的引用; 这些操作并不意味着任何形式的复制。

库函数type返回一个描述给定值类型的字符串(参见§6.1)。

2.2 - 环境与全球环境
如将在要讨论§3.2和§3.3.3,到*名称的任何引用(即,不束缚于任何声明的名称)var 在语法翻译成_ENV.var。而且,每个块都在一个名为_ENV(参见§3.3.2)的外部局部变量的范围内编译,因此_ENV它本身永远不是块中的*名称。

尽管存在这个外部_ENV变量和*名称的翻译 ,但这_ENV是一个完全规则的名称。特别是,您可以使用该名称定义新变量和参数。每个对*名称的引用都使用_ENV在程序中该点可见的,遵循Lua的常见可见性规则(参见§3.5)。

用作值的任何表_ENV称为环境。

Lua保持着一个称为全球环境的杰出环境。该值保存在C注册表中的特殊索引处(参见§4.5)。在Lua中,全局变量_G用相同的值初始化。(_G从不在内部使用。)

当Lua加载块时,其_ENVupvalue 的默认值是全局环境(请参阅参考资料load)。因此,默认情况下,Lua代码中的*名称是指全局环境中的条目(因此,它们也称为全局变量)。此外,所有标准库都加载到全局环境中,并且那里的一些功能在该环境中运行。您可以使用load(或loadfile)加载具有不同环境的块。(在C中,您必须加载块,然后更改其第一个upvalue的值。)

2.3 - 错误处理
因为Lua是一种嵌入式扩展语言,所以所有Lua操作都从宿主程序中的C代码开始,从Lua库调用一个函数。(当您使用Lua standalone时,lua应用程序是主程序。)每当编译或执行Lua块时发生错误,控制权将返回主机,主机可以采取适当的措施(例如打印错误消息)。

Lua代码可以通过调用error函数显式生成错误 。如果需要捕获Lua中的错误,可以使用pcall或xpcall 以受保护模式调用给定函数。

每当出现错误时,都会传播错误对象(也称为错误消息),其中包含有关错误的信息。Lua本身只生成错误对象是字符串的错误,但程序可能会生成任何值的错误作为错误对象。由Lua程序或其主机来处理这样的错误对象。

当您使用xpcall或时lua_pcall,您可以 在出现错误时调用消息处理程序。使用原始错误对象调用此函数并返回新的错误对象。它在错误展开堆栈之前调用,以便它可以收集有关错误的更多信息,例如通过检查堆栈并创建堆栈回溯。此消息处理程序仍受受保护的调用保护; 所以,消息处理程序中的错误将再次调用消息处理程序。如果这个循环持续太长时间,Lua会打破它并返回一个适当的消息。(仅针对常规运行时错误调用消息处理程序。在运行终结器时,不会调用内存分配错误或错误。)

2.4 - Metatables和Metamethods
Lua中的每个值都可以有一个metatable。此metatable是一个普通的Lua表,它定义了某些特殊操作下原始值的行为。您可以通过在其元表中设置特定字段来更改操作行为的几个方面。例如,当非数字值是加法的操作数时,Lua检查__add值的metatable 字段“ ”中的函数。如果找到一个,Lua会调用此函数来执行添加。

metatable中每个事件的键是一个字符串,其事件名称前缀为两个下划线; 相应的值称为metamethods。在前面的示例中,键是“ __add”,而metamethod是执行添加的函数。除非另有说明,否则metamethods应该是函数值。

您可以使用该getmetatable函数查询任何值的元表。Lua使用原始访问查询元数据中的元方法(请参阅参考资料rawget)。因此,为了检索ev对象中事件的元方法o,Lua完全等效于以下代码:

rawget(getmetatable(o)或{},“__ ev ”)
您可以使用该setmetatable函数替换表的元表。您无法从Lua代码更改其他类型的元表(除非使用调试库(第6.10节)); 你应该使用C API。

表和完整的userdata具有单独的元表(尽管多个表和userdata可以共享其元表)。所有其他类型的值每种类型共享一个metatable; 也就是说,所有数字都有一个metatable,一个用于所有字符串,等等。默认情况下,一个值没有metatable,但是字符串库为字符串类型设置了metatable(参见§6.4)。

metatable控制对象在算术运算,按位运算,顺序比较,串联,长度运算,调用和索引中的行为方式。当用户数据或表被垃圾收集时,metatable也可以定义要调用的函数(第2.5节)。

对于一元运算符(否定,长度和按位NOT),计算元方法并使用虚拟的第二个操作数调用,等于第一个操作数。这个额外的操作数只是为了简化Lua的内部(通过使这些操作符像二进制操作一样),并且可能在将来的版本中被删除。(对于大多数用途,这个额外的操作数是无关紧要的。)

接下来给出由元表控制的事件的详细列表。每个操作由其相应的键标识。

__add: addition(+)操作。如果添加的任何操作数不是数字(也不是对数字强制的字符串),Lua将尝试调用metamethod。首先,Lua将检查第一个操作数(即使它是有效的)。如果该操作数没有定义元方法__add,那么Lua将检查第二个操作数。如果Lua可以找到一个metamethod,它会将两个操作数作为参数调用metamethod,并且调用的结果(调整为一个值)是操作的结果。否则,它会引发错误。
__sub: 减法(-)操作。行为类似于添加操作。
__mul: multiplication(*)操作。行为类似于添加操作。
__div: division(/)操作。行为类似于添加操作。
__mod: modulo(%)操作。行为类似于添加操作。
__pow: exponentiation(^)操作。行为类似于添加操作。
__unm: 否定(一元-)操作。行为类似于添加操作。
__idiv: floor division(//)操作。行为类似于添加操作。
__band: 按位AND(&)操作。类似于加法运算的行为,除了如果任何操作数既不是整数也不是对整数可强制的值,Lua将尝试元方法(参见§3.4.3)。
__bor: 按位OR(|)操作。行为类似于按位AND运算。
__bxor: 按位异或(二进制~)运算。行为类似于按位AND运算。
__bnot: 按位NOT(一元~)运算。行为类似于按位AND运算。
__shl: 按位左移(<<)运算。行为类似于按位AND运算。
__shr: 按位右移(>>)运算。行为类似于按位AND运算。
__concat: concatenation(..)操作。类似于加法运算的行为,除了如果任何操作数既不是字符串也不是数字(对于字符串总是可强制的),Lua将尝试元方法。
__len: length(#)操作。如果对象不是字符串,Lua将尝试其metamethod。如果存在metame方法,Lua将该对象作为参数调用,并且调用的结果(始终调整为一个值)是操作的结果。如果没有metamethod但对象是表,则Lua使用表长度操作(参见§3.4.7)。否则,Lua会引发错误。
__eq: equal(==)操作。类似于加法运算的行为,除了Lua将仅在被比较的值既是表或两个完整用户数据并且它们不是原始相等时尝试元方法。调用的结果总是转换为布尔值。
__lt: 小于(<)操作。行为类似于加法运算,除了Lua只在被比较的值既不是数字也不是两个字符串时都会尝试元方法。调用的结果总是转换为布尔值。
__le: 较少的equal(<=)操作。与其他操作不同,不太相等的操作可以使用两个不同的事件。首先,Lua __le在两个操作数中寻找元方法,就像在少于操作中一样。如果它找不到这样的元方法,那么它将尝试__ltmetame方法,假设a <= b相当于not (b < a)。与其他比较运算符一样,结果始终是布尔值。(__lt在将来的版本中可以删除此事件的使用;它也比真正的__le元方法慢。)
__index: 索引访问操作table[key]。当事件table不是表或key不存在时,会发生此事件table。查找了metamethod table。
尽管有这个名字,这个事件的元方法可以是函数或表。如果它是一个函数,则使用table和key作为参数调用它,并且调用的结果(调整为一个值)是操作的结果。如果它是一个表,则最终结果是将该表索引的结果key。(这种索引是常规的,而不是原始的,因此可以触发另一种元方法。)

__newindex: 索引分配table[key] = value。与索引事件一样,此事件发生在table不是表或key不存在时table。查找了metamethod table。
与索引一样,此事件的元方法可以是函数或表。如果它是一个功能,它被称为用table,key以及value作为参数。如果它是一个表,Lua会使用相同的键和值对此表进行索引分配。(这项任务是有规律的,不是原始的,因此可以触发另一种元方法。)

每当有一个__newindex元方法时,Lua就不会执行原始赋值。(如果有必要,metamethod本身可以调用rawset 来进行赋值。)

__call: 通话操作func(args)。当Lua尝试调用非函数值(即,func不是函数)时,会发生此事件。查找了metamethod func。如果存在,则使用func第一个参数调用元方法,然后调用原始调用(args)的参数。调用的所有结果都是操作的结果。(这是唯一允许多个结果的元方法。)
在将其设置为某个对象的元表之前,将所有需要的元方法添加到表中是一种很好的做法。特别是,元__gc方法仅在遵循此顺序时才起作用(参见§2.5.1)。

因为元表是常规表,所以它们可以包含任意字段,而不仅仅是上面定义的事件名称。标准库中的某些函数(例如tostring)使用元表中的其他字段用于它们自己的目的。

2.5 - 垃圾收集
Lua执行自动内存管理。这意味着您不必担心为新对象分配内存或在不再需要对象时释放它。Lua通过运行垃圾收集器来自动管理内存,以收集所有死对象 (即不再可从Lua访问的对象)。Lua使用的所有内存都受自动管理:字符串,表,用户数据,函数,线程,内部结构等。

Lua实现了一个增量的标记和扫描收集器。它使用两个数字来控制其垃圾收集周期:垃圾收集器暂停和垃圾收集器步骤倍增器。两者都使用百分点作为单位(例如,值100表示​​内部值为1)。

垃圾收集器暂停控制收集器在开始新循环之前等待的时间。较大的值使收集器不那么具有攻击性。小于100的值意味着收集器不会等待开始新的循环。值200表示收集器在开始新循环之前等待使用的总内存加倍。

垃圾收集器步骤乘法器控制收集器相对于内存分配的相对速度。较大的值会使收集器更具侵略性,但也会增加每个增量步骤的大小。您不应该使用小于100的值,因为它们会使收集器太慢并且可能导致收集器永远不会完成一个循环。默认值为200,这意味着收集器以“两倍”的内存分配速度运行。

如果将步长乘数设置为一个非常大的数字(大于程序可能使用的最大字节数的10%),则收集器的行为就像一个世界上的停止收集器。如果然后将暂停设置为200,则收集器的行为与旧的Lua版本相同,每次Lua将其内存使用量增加一倍时执行完整集合。

您可以通过lua_gc在C或collectgarbageLua中调用来更改这些数字。您也可以使用这些函数直接控制收集器(例如,停止并重新启动它)。

2.5.1 - 垃圾收集Metamethods
您可以为表设置垃圾收集器元方法,并使用C API为完整用户数据设置(参见§2.4)。这些元方法也称为终结器。终结器允许您协调Lua的垃圾收集与外部资源管理(例如关闭文件,网络或数据库连接,或释放您自己的内存)。

对于要在收集时完成的对象(表或用户数据),必须将其标记为最终确定。在设置metatable时标记对象以进行最终化,并且metatable具有由字符串“ __gc” 索引的字段。请注意,如果在没有__gc字段的情况下设置元表,然后在元表中创建该字段,则不会标记该对象以进行最终化。

当标记的对象变为垃圾时,垃圾收集器不会立即收集它。相反,Lua把它放在一个列表中。收集完成后,Lua会查看该列表。对于列表中的每个对象,它检查对象的__gcmetamethod:如果它是一个函数,Lua将该对象作为其单个参数调用它; 如果metame方法不是函数,Lua就会忽略它。

在每个垃圾收集周期结束时,对象的终结器按照与该周期中收集的对象被标记为完成的相反顺序进行调用; 也就是说,要调用的第一个终结器是与程序中最后标记的对象相关联的终结器。每个终结器的执行可以在执行常规代码期间的任何时刻发生。

因为正在收集的对象仍然必须由终结器使用,所以该对象(以及只能通过它访问的其他对象)必须由Lua 复活。通常,这种复活是暂时的,并且在下一个垃圾收集周期中释放对象存储器。但是,如果终结器将对象存储在某个全局位置(例如,全局变量),则复活是永久性的。此外,如果终结器再次标记最终化的终结对象,则将在下一个无法访问对象的循环中再次调用其终结器。在任何情况下,仅在GC循环中释放对象存储器,其中对象不可到达且未标记为完成。

当你关闭一个状态(参见lua_close参考资料)时,Lua按照标记的相反顺序调用标记为完成的所有对象的终结符。如果任何终结器在该阶段标记要收集的对象,则这些标记无效。

2.5.2 - 弱表
一个弱表是一个表,它的元素是 弱引用。垃圾收集器忽略弱引用。换句话说,如果对对象的唯一引用是弱引用,则垃圾收集器将收集该对象。

弱表可以具有弱键,弱值或两者。具有弱值的表允许收集其值,但会阻止其键的收集。具有弱键和弱值的表允许收集键和值。在任何情况下,如果收集了密钥或值,则从表中删除整个对。表的弱点__mode由其元表的字段控制 。如果该__mode字段是包含字符' k' 的字符串,则表中的键很弱。如果__mode包含' v',则表中的值很弱。

具有弱键和强值的表也称为ephemeron表。在ephemeron表中,只有在其密钥可访问时,才认为该值是可到达的。特别是,如果对键的唯一引用通过其值,则删除该对。

表的弱点的任何变化可能仅在下一个收集周期生效。特别是,如果您将弱点更改为更强的模式,Lua可能会在更改生效之前从该表中收集一些项目。

仅从弱表中删除具有显式构造的对象。诸如数字和轻C函数之类的值不受垃圾收集的影响,因此不会从弱表中删除(除非收集它们的相关值)。虽然字符串可以进行垃圾回收,但它们没有明确的构造,因此不会从弱表中删除。

复活的对象(即,最终确定的对象和仅通过最终确定的对象可访问的对象)在弱表中具有特殊行为。它们在运行终结器之前从弱值中删除,但在运行终结器后,实际释放这些对象时,仅在下一个集合中从弱键中删除它们。此行为允许终结器通过弱表访问与对象关联的属性。

如果在收集周期中复活的对象中存在弱表,则在下一个周期之前可能无法正确清除它。

2.6 - 协同程序
Lua支持协程,也称为协作多线程。Lua中的协程代表一个独立的执行线程。但是,与多线程系统中的线程不同,协程只通过显式调用yield函数来暂停其执行。

你通过调用创建一个协同程序coroutine.create。它唯一的论点是一个函数,它是协程的主要功能。该create函数只创建一个新的协同程序并返回一个句柄(一个类型为thread的对象); 它没有启动协程。

你通过调用执行一个协同程序coroutine.resume。当你第一次调用时coroutine.resume,作为第一个参数传递一个返回的线程coroutine.create,协同程序通过调用它的main函数来启动它的执行。传递给的额外参数coroutine.resume作为参数传递给该函数。协程开始运行后,它会一直运行直到它终止或产生。

协程可以通过两种方式终止其执行:通常,当其主函数返回时(显式或隐式地,在最后一条指令之后); 如果出现无保护错误,则异常。在正常终止的情况下, coroutine.resume返回true,以及coroutine main函数返回的任何值。如果出现错误,则coroutine.resume返回false 加上错误对象。

一个协程通过调用产生coroutine.yield。当协程生成时,相应的coroutine.resume返回立即返回,即使在嵌套函数调用内发生了收益(也就是说,不在main函数中,而是在main函数直接或间接调用的函数中)。在yield的情况下,coroutine.resume也返回true,加上传递给的任何值coroutine.yield。下次你恢复相同的协程时,它会从它产生的点继续执行,并调用coroutine.yield返回传递给它的任何额外参数coroutine.resume。

就像coroutine.create,该coroutine.wrap函数还创建了一个协程,但它不是返回协程本身,而是返回一个函数,当被调用时,它恢复协程。传递给此函数的任何参数都作为额外的参数coroutine.resume。 coroutine.wrap返回coroutine.resume除第一个(布尔错误代码)之外的所有返回值。不同coroutine.resume, coroutine.wrap不会发现错误; 任何错误都会传播给调用者。

作为协同程序如何工作的示例,请考虑以下代码:

功能foo(a)
print(“foo”,a)
return coroutine.yield(2 * a)
结束

co = coroutine.create(function(a,b)
print(“co-body”,a,b)
本地r = foo(a + 1)
print(“co-body”,r)
本地r,s = coroutine.yield(a + b,ab)
print(“co-body”,r,s)
返回b,“结束”
结束)

print(“main”,coroutine.resume(co,1,10))
print(“main”,coroutine.resume(co,“r”))
print(“main”,coroutine.resume(co,“x”,“y”))
print(“main”,coroutine.resume(co,“x”,“y”))
运行它时,它会产生以下输出:

共同体1 10
foo 2
主要真实4
共同体
主要是真实的11-9
共同体xy
主要真正的10结束
主要的假不能恢复死coroutine
您还可以创建和操作通过C API协同程序:看功能lua_newthread,lua_resume和lua_yield。

3 - 语言
本节描述了Lua的lexis,语法和语义。换句话说,本节描述了哪些令牌有效,它们如何组合以及它们的组合意味着什么。

语言结构将使用通常的扩展BNF表示法来解释,其中{ a }表示0或更多a,而[ a ]表示可选的a。非终端显示为非终端,关键字显示为kword,其他终端符号显示为' = '。Lua的完整语法可以在 本手册末尾的§9中找到。

3.1 - 词汇约定
Lua是一种*形式的语言。它忽略了空格(包括新行)和词法元素(标记)之间的注释,除了名称和关键字之间的分隔符。

Lua中的名称 (也称为标识符)可以是任何字母,数字和下划线字符串,不以数字开头而不是保留字。标识符用于命名变量,表字段和标签。

以下关键字是保留的,不能用作名称:

并打破其他的结果
函数goto为false,如果在
当地没有或重复返回
然后真实,直到
Lua是一种区分大小写的语言: and是一个保留字,但And它AND 是两个不同的有效名称。作为惯例,程序应避免创建以下划线开头的名称,后跟一个或多个大写字母(例如_VERSION)。

以下字符串表示其他标记:

+ - * /%^#
&〜| << >> //
==〜= <=> = <> =
(){} [] ::
; :,。......
甲短文本字符串 可以通过匹配单引号或双引号进行分隔,并且可以包含下面的C状的转义序列:“ \a”(钟形),“ \b”(退格),“ \f”(形式进料),“ \n”(换行), ' \r'(回车),' \t'(水平标签),' \v'(垂直标签),' \\'(反斜杠),' \"'(引号[双引号])和' \''(撇号[单引号])。反斜杠后跟换行符会在字符串中生成换行符。逃脱序列'\z'跳过以下白色空格字符,包括换行符; 将长文字字符串分解并缩进多行而不将新行和空格添加到字符串内容中特别有用。短文字字符串不能包含未转义的换行符,也不能包含未形成有效转义序列的转义符。

我们可以通过其数值(包括嵌入的零)指定短文字字符串中的任何字节。这可以通过转义序列来完成,其中XX是正好两个十六进制数字的序列,或者使用转义序列,其中ddd是最多三个十进制数字的序列。(请注意,如果一个十进制转义序列后跟一个数字,则必须使用正好三位数表示。) \xXX\ddd

可以将Unicode字符的UTF-8编码插入带有转义序列的文字字符串中 (请注意必需的括号),其中XXX是一个表示字符代码点的一个或多个十六进制数字的序列。 \u{XXX}

也可以使用长括号括起来的长格式来定义文字字符串。我们将n级的开口长支架定义为开口方括号,后跟n个等号后跟另一个开口方括号。因此,写入级别0 [[的开始长括号,将级别1的开始长括号写为[=[,依此类推。甲长括号被类似地定义; 例如,级别4的结束长括号写为 ]====]。一个长的文字从任何级别的开口长支架开始,并在同一级别的第一个关闭长支架处结束。它可以包含除同一级别的右括号之外的任何文本。这种括号中的文字可以运行多行,不解释任何转义序列,并忽略任何其他级别的长括号。任何类型的行结束序列(回车符,换行符,回车后跟换行符,换行符后换行符)都会转换为简单的换行符。

为方便起见,当开头长括号后面紧跟换行符时,换行符不包含在字符串中。例如,在使用ASCII的系统中(其中' a'编码为97,换行符编码为10,' 1'编码为49),下面的五个文字字符串表示相同的字符串:

a ='alo \ n123“'
a =“alo \ n123 \”“
a ='\ 97lo \ 10 \ 04923“'
a = [[alo
123" ]]
a = [== [
ALO
123" ] ==]
未受先前规则明确影响的文字字符串中的任何字节都表示自身。但是,Lua打开文件以在文本模式下进行解析,并且系统文件函数可能存在某些控制字符的问题。因此,将非文本数据表示为带有非文本字符的显式转义序列的带引号的文字更安全。

甲数字常数(或标记)可以与一个可选的小数部分和可选的小数指数被写入,由字母“标记e”或“ E”。Lua也接受十六进制常量,以0x或开头0X。十六进制常量也接受可选的小数部分加上可选的二进制指数,用字母' p'或' P' 标记。带小数点或指数的数字常量表示浮点数; 否则,如果其值适合整数,则表示整数。有效整数常量的示例是

3 345 0xff 0xBEBADA
有效浮点常量的示例是

3.0 3.1416 314.16e-2 0.31416E1 34e1
0x0.1E 0xA23p-4 0X1.921FB54442D18P + 1
一个注释开始用双连字符(--)的字符串以外的任何地方。如果紧接着的文本--不是开头长括号,则注释是一个简短的注释,一直运行到行的结尾。否则,它是一个长注释,直到相应的结束长括号。长注释经常用于临时禁用代码。

3.2 - 变量
变量是存储值的地方。Lua中有三种变量:全局变量,局部变量和表字段。

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

var :: = Name
名称表示标识符,如§3.1中所定义。

除非明确声明为本地变量名称,否则任何变量名称都被假定为全局变量名称(参见§3.3.7)。局部变量是词法范围的:局部变量可以通过其范围内定义的函数*访问(参见§3.5)。

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

方括号用于索引表:

var :: = prefixexp' [ 'exp' ] '
访问表字段的含义可以通过元表更改(参见§2.4)。

语法var.Name只是语法糖 var["Name"]:

var :: = prefixexp' 。' 名称
对全局变量的访问x 等同于_ENV.x。由于编译块的方式, _ENV永远不是全局名称(参见§2.2)。

3.3 - 陈述
Lua支持几乎常规的语句集,类似于Pascal或C中的语句。该集包括赋值,控制结构,函数调用和变量声明。

3.3.1 - 块
块是一个语句列表,按顺序执行:

block :: = {stat}
Lua 有空语句 ,允许您用分号分隔语句,用分号开始一个块或按顺序写两个分号:

stat :: =' ; “
函数调用和赋值可以以左括号开头。这种可能性导致了Lua语法的模糊性。请考虑以下片段:

a = b + c
(打印或io.write)('完成')
语法可以通过两种方式看到它:

a = b + c(print或io.write)('done')

a = b + c; (打印或io.write)('完成')
当前解析器总是以第一种方式看到这样的结构,将开括号解释为调用参数的开始。为避免这种歧义,最好始终在以括号开头的分号语句之前:

;(打印或io.write)('完成')
可以明确分隔块以生成单个语句:

stat :: = do block end
显式块对于控制变量声明的范围很有用。显式块有时也用于在另一个块的中间添加一个return语句(参见§3.3.4)。

3.3.2 - 大块
Lua的编译单元称为块。从语法上讲,块只是一个块:

chunk :: = block
Lua将一个块作为具有可变数量参数的匿名函数的主体处理(参见§3.4.11)。因此,块可以定义局部变量,接收参数和返回值。此外,这种匿名函数被编译为外部局部变量的范围_ENV(见§2.2)。结果函数始终具有_ENV唯一的up值,即使它不使用该变量。

块可以存储在宿主程序内的文件或字符串中。为了执行一个块,Lua首先加载它,将块的代码预编译为虚拟机的指令,然后Lua用虚拟机的解释器执行编译的代码。

块也可以预编译成二进制形式; 详情请参阅程序luac和功能string.dump。源代码和编译形式的程序是可以互换的; Lua会自动检测文件类型并采取相应措施(请参阅参考资料load)。

3.3.3 - 分配
Lua允许多项任务。因此,赋值语法定义左侧的变量列表和右侧的表达式列表。两个列表中的元素用逗号分隔:

stat :: = varlist' = 'explist
varlist :: = var {' , 'var}
explist :: = exp {' , 'exp}
表达式在§3.4中讨论。

在赋值之前,将值列表调整为变量列表的长度。如果值多于所需值,则会丢弃多余的值。如果值少于所需值,则列表将根据需要扩展为 nil。如果表达式列表以函数调用结束,则该调用返回的所有值在调整之前输入值列表(除非将调用括在括号中;请参阅§3.4)。

赋值语句首先计算其所有表达式,然后才执行赋值。因此代码

我= 3
我,a [i] = i + 1,20
设置a[3]为20,不会影响,a[4] 因为i在a[i]分配之前评估(到3)。同样,该行

x,y = y,x
的交流值x和y,和

x,y,z = y,z,x
周期性的置换的值x,y和z。

对全局名称x = val 的赋值等同于赋值 _ENV.x = val(参见§2.2)。

表字段和全局变量(实际上也是表字段)的赋值的含义可以通过元表更改(参见§2.4)。

3.3.4 - 控制结构
控制结构 if,while和repeat具有通常的含义和熟悉的语法:

stat :: = while exp do block end
stat :: = 重复阻止直到 exp
stat :: = if exp then block { elseif exp then block} [ else block] end
Lua还有一种for语句,有两种形式(见§3.3.5)。

控制结构的条件表达式可以返回任何值。这两种假和零被认为是假的。不同于nil和false的所有值都被认为是真的(特别是,数字0和空字符串也是真的)。

在repeat - until循环中,内部块不以until关键字结束,而是仅在条件之后。因此,条件可以引用循环块内声明的局部变量。

将跳转语句将程序控制的标签。出于语法原因,Lua中的标签也被视为语句:

stat :: = goto名称
stat :: =标签
label :: =' :: 'Name' :: '
标签在定义它的整个块中是可见的,除了嵌套块内,其中定义了具有相同名称的标签并在嵌套函数内。只要goto没有进入局部变量的范围,它就可以跳转到任何可见标签。

标签和空语句称为void语句,因为它们不执行任何操作。

在休息的语句终止执行 ,同时,重复,或用于循环,跳到循环之后的下一条语句:

stat :: = break
甲休息结束该最内层循环。

该返回语句用来从一功能或一组块(这是一个匿名功能)返回值。函数可以返回多个值,因此return语句的语法是

stat :: = return [explist] [' ; “]
在返回语句只能写成块的最后陈述。如果确实需要在块的中间返回,则可以使用显式内部块,如在习语中do return end,因为现在返回是其(内部)块中的最后一个语句。

3.3.5 - 声明
该对语句有两种形式:一个数字和一个通用的。

数值为同时控制变量通过算术级数运行循环重复的代码块。它具有以下语法:

stat :: = for Name' = 'exp' , 'exp [' , 'exp] do block end
从第一个exp的值开始重复 该块的名称,直到它通过第三个exp的步骤通过第二个exp。更确切地说,一个for语句就像

对于v = e1,e2,e3做阻止结束
相当于代码:


本地变种,极限,步骤 = tonumber(E1),tonumber(E2),tonumber(E3)
如果不是(var和limit和step)则error()end
var = var - step
虽然如此
var = var + step
if(step > = 0且var > limit)或(step <0和var < limit)然后
打破
结束
本地v = var

结束
结束
请注意以下事项:

在循环开始之前,所有三个控制表达式仅被评估一次。它们都必须导致数字。
var,, limit和step是不可见的变量。此处显示的名称仅用于说明目的。
如果不存在第三表达式(步骤),则使用步骤1。
您可以使用break和goto退出for循环。
循环变量v是循环体的局部变量。如果在循环后需要其值,请在退出循环之前将其分配给另一个变量。
泛型for语句适用于函数,称为迭代器。在每次迭代时,调用迭代器函数以生成新值,在此新值为nil时停止。泛型for循环具有以下语法:

STAT :: = 对于名称列表中 explist 不阻止端
名称列表:: = {名称“ ”名称}
一个for语句就像

对于var_1,...,explist中的var_n执行块结束
相当于代码:


local f,s,var = explist
虽然如此
local var_1,...,var_n = f(s,var)
如果var_1 == nil则断开结束
var = var_1

结束
结束
请注意以下事项:

explist仅评估一次。其结果是迭代器函数,状态和第一个迭代器变量的初始值。
f,, s和var是不可见的变量。这些名称仅供参考。
您可以使用break来退出for循环。
循环变量var_i是循环的局部变量; 之后,你不能用自己的价值观为目的。如果需要这些值,则在断开或退出循环之前将它们分配给其他变量。
3.3.6 - 函数调用作为语句
为了允许可能的副作用,函数调用可以作为语句执行:

stat :: = functioncall
在这种情况下,所有返回的值都将被丢弃。函数调用在§3.4.10中解释。

3.3.7 - 本地声明
局部变量可以在块内的任何位置声明。声明可以包括初始分配:

stat :: = local namelist [' = 'explist]
如果存在,初始赋值具有与多赋值相同的语义(参见§3.3.3)。否则,所有变量都用nil初始化。

块也是一个块(参见§3.3.2),因此局部变量可以在任何显式块之外的块中声明。

局部变量的可见性规则在§3.5中解释。

3.4 - 表达式
Lua中的基本表达式如下:

exp :: = prefixexp
exp :: = nil | 假 | 真正
exp :: =数字
exp :: = LiteralString
exp :: = functiondef
exp :: = tableconstructor
exp :: =' ... '
exp :: = exp binop exp
exp :: = unop exp
prefixexp :: = var | functioncall | ' ( 'exp' ) '
数字和文字字符串在§3.1中解释; 变量在§3.2中解释; 函数定义在§3.4.11中解释; 函数调用在§3.4.10中解释; 表构造函数在§3.4.9中解释。Vararg表达式由三个点(' ...')表示,只能在直接在vararg函数内部时使用; 它们在§3.4.11中解释。

二元运算符包括算术运算符(参见§3.4.1),按位运算符(参见§3.4.2),关系运算符(参见§3.4.4),逻辑运算符(参见§3.4.5)和连接运算符(参见§) 3.4.6)。一元运算符包括一元减号(见§3.4.1),一元按位NOT(见§3.4.2),一元逻辑非(见§3.4.5)和一元长度运算符(见§3.4.7) 。

函数调用和vararg表达式都可能导致多个值。如果函数调用用作语句(参见§3.3.6),则其返回列表将调整为零元素,从而丢弃所有返回的值。如果表达式用作表达式列表的最后一个(或唯一)元素,则不进行任何调整(除非表达式括在括号中)。在所有其他上下文中,Lua将结果列表调整为一个元素,要么丢弃除第一个之外的所有值,要么在没有值时添加单个nil。

这里有些例子:

f() - 调整为0结果
g(f(),x) - f()调整为1
g(x,f()) - g得到x加上f()的所有结果
a,b,c = f(),x - f()调整为1结果(c变为零)
a,b = ... - a得到第一个vararg参数,b得到
- 第二个(如果有的话,a和b都可以为零)
- 没有相应的vararg论点)

a,b,c = x,f() - f()调整为2个结果
a,b,c = f() - f()调整为3个结果
return f() - 返回f()的所有结果
return ... - 返回所有收到的vararg参数
return x,y,f() - 返回x,y和f()的所有结果
{f()} - 创建一个包含f()所有结果的列表
{...} - 创建一个包含所有vararg参数的列表
{f(),nil} - f()调整为1
括在括号中的任何表达式始终只生成一个值。因此,(f(x,y,z))即使f返回多个值, 也始终是单个值。(的值(f(x,y,z))是由所返回的第一值f 或者零,如果f没有返回任何值。)

3.4.1 - 算术运算符
Lua支持以下算术运算符:

+:另外
-:减法
*:乘法
/:浮动师
//:地板师
%: modulo
^:取幂
-:一元减去
除了取幂和浮点除法之外,算术运算符的工作方式如下:如果两个操作数都是整数,则操作在整数上执行,结果为整数。否则,如果两个操作数都是可以转换为数字的数字或字符串(参见§3.4.3),那么它们将转换为浮点数,操作按照通常的浮点运算规则(通常是IEEE 754标准)执行,结果是浮动。

Exponentiation和float division(/)总是将它们的操作数转换为浮点数,结果总是浮点数。Exponentiation使用ISO C函数pow,因此它也适用于非整数指数。

Floor division(//)是一个将商舍入负无穷大的分区,即其操作数的分区。

模数被定义为将商舍入负无穷大(分层)的除法的余数。

在整数运算中出现溢出的情况下,根据二补码算法的通常规则,所有运算都会回绕。(换句话说,它们将与模数为2 64的唯一可表示整数返回到数学结果。)

3.4.2 - 按位运算符
Lua支持以下按位运算符:

&:按位AND
|:按位OR
~:按位异或
>>:右转
<<:左移
~:一元按位NOT
所有按位运算都将其操作数转换为整数(参见§3.4.3),对这些整数的所有位进行操作,并产生整数。

右移和左移都用零填充空位。负位移向另一个方向移动; 绝对值等于或高于整数中的位数的位移导致零(因为所有位都被移出)。

3.4.3 - 强制和转换
Lua在运行时提供某些类型和表示之间的一些自动转换。按位运算符总是将浮点操作数转换为整数。Exponentiation和float除法总是将整数操作数转换为浮点数。应用于混合数字(整数和浮点数)的所有其他算术运算将整数操作数转换为浮点数; 这被称为通常的规则。根据需要,C API还将整数转换为浮点数并将浮点数转换为整数。此外,字符串连接除了字符串之外还接受数字作为参数。

每当有数字时,Lua也会将字符串转换为数字。

在从整数到浮点数的转换中,如果整数值具有精确的表示形式,那么就是结果。否则,转换得到最接近的较高或最接近的较低可表示值。这种转换永远不会失败。

从float到integer的转换检查float是否具有整数的精确表示(即,float具有整数值,并且它在整数表示的范围内)。如果是,则表示结果。否则,转换失败。

从字符串到数字的转换如下:首先,按照语法和Lua词法分析器的规则将字符串转换为整数或浮点数。(该字符串可能还有前导和尾随空格以及符号。)然后,结果数(浮点数或整数)将转换为上下文所需的类型(浮点数或整数)(例如,强制转换的操作)。

从字符串到数字的所有转换都接受点和当前区域设置标记作为基数字符。(然而,Lua lexer只接受一个点。)

从数字到字符串的转换使用未指定的人类可读格式。要完全控制数字如何转换为字符串,请使用format字符串库中的函数(请参阅参考资料string.format)。

3.4.4 - 关系运算符
Lua支持以下关系运算符:

==:平等
~=:不平等
<:不到
>:大于
<=:更少或相等
>=:更大或更平等
这些运算符总是导致错误或真实。

Equality(==)首先比较其操作数的类型。如果类型不同,则结果为false。否则,比较操作数的值。字符串以明显的方式进行比较。如果它们表示相同的数学值,则数字相等。

通过引用比较表,userdata和线程:只有当两个对象是同一个对象时才认为它们是相等的。每次创建新对象(表,用户数据或线程)时,此新对象都不同于以前存在的任何对象。闭包总是等于它自己。具有任何可检测差异(不同行为,不同定义)的闭包总是不同的。在不同时间创建但没有可检测到的差异的闭包可以被分类为相同或不同(取决于内部缓存细节)。

您可以使用“eq”元方法更改Lua比较表和userdata的方式(参见§2.4)。

等式比较不会将字符串转换为数字,反之亦然。因此,"0"==0计算结果为假,并t[0]和t["0"]在表中表示不同的条目。

运算符~=恰好是对equality(==)的否定。

订单操作符的工作方式如下。如果两个参数都是数字,则根据它们的数学值(不管它们的子类型)进行比较。否则,如果两个参数都是字符串,则根据当前区域设置比较它们的值。否则,Lua会尝试调用“lt”或“le”元方法(参见§2.4)。比较a > b被翻译成b < a 并被a >= b翻译成b <= a。

遵循IEEE 754标准,NaN被认为既不小于,也不等于,也不大于任何值(包括其本身)。

3.4.5 - 逻辑运算符
Lua中的逻辑运算符是 和,或者是,而不是。与控制结构一样(参见§3.3.4),所有逻辑运算符都将false和nil视为false,将其他任何内容视为true。

否定运算符并不总是返回false或true。如果此值为false或nil,则为连接运算符并返回其第一个参数; 否则,并且返回第二个参数。如果此值与nil和false不同,则析取运算符或返回其第一个参数; 否则,或返回其第二个参数。既与和或使用短路评价; 也就是说,仅在必要时评估第二个操作数。这里有些例子:

10或20 - > 10
10或错误() - > 10
零或“a” - >“a”
零和10 - >零
false和error() - > false
假和零 - >假
false或nil - > nil
10和20 - > 20
(在本手册中, -->表示前面表达式的结果。)

3.4.6 - 连接
Lua中的字符串连接运算符由两个点(' ..')表示。如果两个操作数都是字符串或数字,则它们将根据§3.4.3中描述的规则转换为字符串。否则,__concat调用metamethod(参见§2.4)。

3.4.7 - 长度算子
长度运算符由一元前缀运算符表示#。

字符串的长度是它的字节数(也就是每个字符是一个字节时字符串长度的通常含义)。

应用于表的长度运算符返回该表中的边框。表中的边框t是满足以下条件的任何自然数:

(border == 0或t [border]〜= nil)和t [border + 1] == nil
换句话说,边框是表中的任何(自然)索引,其中非零值后跟零值(或者当索引1为零时为零)。

只有一个边框的表称为序列。例如,该表{10, 20, 30, 40, 50}是一个序列,因为它只有一个边框(5)。该表{10, 20, 30, nil, 50}有两个边框(3和5),因此它不是一个序列。该表{nil, 20, 30, nil, nil, 60, nil} 有三个边框(0,3和6),所以它也不是一个序列。该表{}是带边框0的序列。请注意,非自然键不会干扰表是否为序列。

何时t是序列, #t返回其唯一的边界,这对应于序列长度的直观概念。当t不是序列时, #t可以返回其任何边界。(确切的一个取决于表的内部表示的细节,而这又取决于表的填充方式和非数字键的内存地址。)

表的长度的计算具有保证的最差时间O(log n),其中n是表中最大的自然键。

程序可以通过元方法修改长度运算符对任何值的行为,但是字符串可以通过元方法__len修改(参见§2.4)。

3.4.8 - 优先顺序
Lua中的运算符优先级遵循下表,从较低优先级到较高优先级:

要么

<> <=> =〜= ==
|


<< >>
..
+ -
* / //%
一元运算符(不是# - 〜)
^
像往常一样,您可以使用括号来更改表达式的优先级。连接(' ..')和取幂(' ^')运算符是右关联的。所有其他二元运算符都是左关联的。

3.4.9 - 表构造函数
表构造函数是创建表的表达式。每次评估构造函数时,都会创建一个新表。构造函数可用于创建空表或创建表并初始化其某些字段。构造函数的一般语法是

tableconstructor :: =' { '[fieldlist]' } '
fieldlist :: = field {fieldsep field} [fieldsep]
field :: =' [ 'exp' ] '' = 'exp | 名称' = 'exp | EXP
fieldsep :: =' , '| ' ; “
表单的每个字段都会[exp1] = exp2向新表添加一个带键exp1和值的条目exp2。表格的字段name = exp相当于 ["name"] = exp。最后,表单的字段exp等效于 [i] = exp,其中i以1开头的连续整数。其他格式的字段不影响此计数。例如,

a = {[f(1)] = g; “x”,“y”; x = 1,f(x),[30] = 23; 45}
相当于


本地t = {}
t [f(1)] = g
t [1] =“x” - 第1次曝光
t [2] =“y” - 第二次曝光
tx = 1 - t [“x”] = 1
t [3] = f(x) - 第3个exp
t [30] = 23
t [4] = 45 - 第4次exp
a = t
结束
构造函数中赋值的顺序未定义。(此顺序仅在有重复键时才有意义。)

如果列表中的最后一个字段具有表单exp ,并且表达式是函数调用或vararg表达式,则此表达式返回的所有值将连续输入列表(请参见§3.4.10)。

字段列表可以有一个可选的尾随分隔符,以方便机器生成的代码。

3.4.10 - 函数调用
Lua中的函数调用具有以下语法:

functioncall :: = prefixexp args
在函数调用中,首先计算prefixexp和args。如果prefixexp的值具有type 函数,则使用给定的参数调用此函数。否则,调用prefixexp“call”元方法,将prefixexp的值作为第一个参数,后跟原始调用参数(参见§2.4)。

表格

functioncall :: = prefixexp' : '名称args
可以用来称呼“方法”。一个调用 是语法糖,除了只评估一次。 v:name(args)v.name(v,args)v

参数具有以下语法:

args :: =' ( '[explist]' ) '
args :: = tableconstructor
args :: = LiteralString
在调用之前计算所有参数表达式。形式的调用是语法糖; 也就是说,参数列表是一个新表。形式 (或或)的调用是语法糖; 也就是说,参数列表是单个文字字符串。 f{fields}f({fields})f'string'f"string"f[[string]]f('string')

表单调用称为尾调用。Lua实现了正确的尾调用 (或正确的尾递归):在尾调用中,被调用函数重用调用函数的堆栈条目。因此,程序可以执行的嵌套尾调用的数量没有限制。但是,尾调用会删除有关调用函数的所有调试信息。请注意,尾调用只发生在特定的语法中,其中返回只有一个函数调用作为参数; 这种语法使调用函数完全返回被调用函数的返回值。因此,以下示例都不是尾调用: return functioncall

return(f(x)) - 结果调整为1
返回2 * f(x)
return x,f(x) - 其他结果
F(X); 返回 - 结果丢弃
返回x或f(x) - 结果调整为1
3.4.11 - 功能定义
函数定义的语法是

functiondef :: = function funcbody
funcbody :: =' ( '[parlist]' ) '阻止结束
以下语法糖简化了函数定义:

stat :: = function funcname funcbody
stat :: = local 函数名称funcbody
funcname :: = Name {' 。'姓名} [' : '姓名]
该声明

函数f()正文结束
翻译成

f = function()正文结束
该声明

函数tabcf()正文结束
翻译成

tabcf = function()正文结束
该声明

局部函数f()体端
翻译成

当地的f; f = function()正文结束
不要

局部f = function()体端
(这仅在函数体包含对的引用时才有所不同f。)

函数定义是可执行表达式,其值具有类型函数。当Lua预编译一个块时,它的所有函数体也都被预编译。然后,每当Lua执行函数定义时,该函数被实例化(或关闭)。此函数实例(或闭包)是表达式的最终值。

参数充当使用参数值初始化的局部变量:

parlist :: = namelist [' , '' ... '] | ' ... '
调用函数时,参数列表将调整为参数列表的长度,除非该函数是vararg函数,该...参数由参数列表末尾的三个点(' ')表示。vararg函数不调整其参数列表; 相反,它收集所有额外的参数,并通过vararg表达式将它们提供给函数,也写成三个点。此表达式的值是所有实际额外参数的列表,类似于具有多个结果的函数。如果在另一个表达式内或表达式列表的中间使用vararg表达式,则将其返回列表调整为一个元素。如果表达式用作表达式列表的最后一个元素,则不进行任何调整(除非最后一个表达式括在括号中)。

例如,请考虑以下定义:

函数f(a,b)结束
函数g(a,b,...)结束
函数r()返回1,2,3结束
然后,我们从参数到参数以及vararg表达式进行以下映射:

调用参数

f(3)a = 3,b =零
f(3,4)a = 3,b = 4
f(3,4,5)a = 3,b = 4
f(r(),10)a = 1,b = 10
f(r())a = 1,b = 2

g(3)a = 3,b = nil,... - >(没有)
g(3,4)a = 3,b = 4,... - >(无)
g(3,4,5,8)a = 3,b = 4,...... - > 5 8
g(5,r())a = 5,b = 1,...... - > 2 3
使用return语句返回结果(参见§3.3.4)。如果控件到达函数的末尾而没有遇到return语句,则函数返回时没有结果。

函数可能返回的值的数量存在系统相关限制。此限制保证大于1000。

在结肠语法用于定义方法,即,具有一个隐含的额外的参数的功能self。因此,声明

功能tabc:f(params)正文结束
是语法糖

tabcf = function(self,params)body end
3.5 - 可见性规则
Lua是一种词汇范围的语言。局部变量的范围从其声明后的第一个语句开始,一直持续到包含声明的最内层块的最后一个非void语句。请考虑以下示例:

x = 10 - 全局变量
做 - 新块
local x = x - new'x',值为10
print(x) - > 10
x = x + 1
做 - 另一个块
局部x = x + 1 - 另一个'x'
print(x) - > 12
结束
print(x) - > 11
结束
print(x) - > 10(全球一个)
请注意,在声明中local x = x,声明的新x声明尚未在范围内,因此第二个x引用外部变量。

由于词法范围规则,局部变量可以由其范围内定义的函数*访问。内部函数使用的局部变量在内部函数内称为upvalue或外部局部变量。

请注意,每次执行本地语句都会定义新的局部变量。请考虑以下示例:

a = {}
本地x = 20
对于i = 1,10做
本地y = 0
a [i] = function()y = y + 1; 返回x + y结束
结束
循环创建十个闭包(即匿名函数的十个实例)。这些闭包中的每一个都使用不同的y变量,而它们都共享相同的变量x。

4 - 应用程序接口
本节介绍Lua的C API,即主机程序可用于与Lua通信的C函数集。所有API函数以及相关类型和常量都在头文件中声明lua.h。

即使我们使用术语“函数”,API中的任何工具也可以作为宏提供。除非另有说明,否则所有这些宏都只使用它们的每个参数一次(除了第一个参数,它总是一个Lua状态),因此不会产生任何隐藏的副作用。

与大多数C库一样,Lua API函数不检查其参数的有效性或一致性。但是,您可以通过使用LUA_USE_APICHECK定义的宏编译Lua来更改此行为。

Lua库是完全可重入的:它没有全局变量。它将所需的所有信息保存在称为Lua状态的动态结构中。

每个Lua状态具有一个或多个线程,其对应于独立的协作执行线。类型lua_State(尽管名称)指的是一个线程。(间接地,通过线程,它还指向与线程关联的Lua状态。)

必须将指向线程的指针作为第一个参数传递给库中的每个函数,除了lua_newstate,它从头创建一个Lua状态并返回一个指向新状态的主线程的指针。

4.1 - 堆栈
Lua使用虚拟堆栈向C传递值。此堆栈中的每个元素表示Lua值(nil,number,string等)。API中的函数可以通过它们接收的Lua状态参数访问此堆栈。

每当Lua调用C时,被调用的函数将获得一个新的堆栈,该堆栈独立于先前的堆栈和仍处于活动状态的C函数堆栈。该堆栈最初包含C函数的任何参数,它是C函数可以存储临时Lua值的地方,并且必须将其结果推送回调用者(请参阅参考资料lua_CFunction)。

为方便起见,API中的大多数查询操作都不遵循严格的堆栈规则。相反,它们可以通过使用索引引用堆栈中的任何元素:正索引表示绝对堆栈位置(从1开始); 负索引表示相对于堆栈顶部的偏移量。更具体地说,如果堆栈有n个元素,则索引1表示第一个元素(即,首先被压入堆栈的元素),索引 n表示最后一个元素; index -1也表示最后一个元素(即顶部的元素),index -n表示第一个元素。

4.2 - 堆栈大小
当您与Lua API交互时,您有责任确保一致性。特别是, 您负责控制堆栈溢出。您可以使用该函数lua_checkstack 确保堆栈有足够的空间来推送新元素。

每当Lua调用C时,它确保堆栈具有至少LUA_MINSTACK额外插槽的空间。 LUA_MINSTACK定义为20,因此通常您不必担心堆栈空间,除非您的代码具有将元素推送到堆栈的循环。

当你在没有固定数量结果的情况下调用Lua函数时(参见lua_call参考资料),Lua确保堆栈有足够的空间容纳所有结果,但它不能确保任何额外的空间。所以,在这样的调用之后推送堆栈中的任何东西之前你应该使用lua_checkstack。

4.3 - 有效和可接受的指数
接收堆栈索引的API中的任何函数仅适用于有效索引或可接受的索引。

甲有效的索引是指存储可修改的Lua值的位置的索引。它包含1和堆栈顶部(1 ≤ abs(index) ≤ top)加上伪索引之间的堆栈索引,它们表示C代码可访问但不在堆栈中的某些位置。伪索引用于访问注册表(参见§4.5)和C函数的upvalues(参见§4.4)。

可以使用可接受的索引调用不需要特定可变位置但仅需要值(例如,查询函数)的函数。一个可以接受的指数可以是任何有效指标,但它也可以分配给栈的空间内栈顶之后的任何积极的指标,也就是指数高达堆栈大小。(注意0绝不是可接受的索引。)除非另有说明,否则A​​PI中的函数使用可接受的索引。

可接受的索引用于在查询堆栈时避免对堆栈顶部进行额外测试。例如,C函数可以查询其第三个参数,而无需首先检查是否存在第三个参数,即无需检查3是否为有效索引。

对于可以使用可接受索引调用的函数,任何无效索引都被视为包含虚拟类型的值LUA_TNONE,其行为类似于nil值。

4.4 - C闭包
当创建C函数时,可以将一些值与它相关联,从而创建一个C闭包 (参见参考资料lua_pushcclosure); 这些值称为upvalues,只要调用它,函数就可以访问它们。

每当调用C函数时,其upvalues都位于特定的伪索引处。这些伪指数由宏产生 lua_upvalueindex。与函数关联的第一个upvalue是索引 lua_upvalueindex(1),依此类推。任何访问,其中n大于当前函数的upvalues的数量(但不大于256,这是一个加上闭包中upvalues的最大数量),产生一个可接受但无效的索引。 lua_upvalueindex(n)

4.5 - 注册表
Lua提供了一个注册表,一个预定义的表,任何C代码都可以使用它来存储它需要存储的任何Lua值。注册表始终位于伪索引处 LUA_REGISTRYINDEX。任何C库都可以将数据存储到此表中,但必须注意选择与其他库使用的键不同的键,以避免冲突。通常,您应该使用包含您的库名称的字符串作为键,或者使用代码中具有C对象地址的轻用户数据,或者您的代码创建的任何Lua对象。与变量名一样,以下划线后跟大写字母开头的字符串键保留给Lua。

注册表中的整数键由引用机制(请参阅参考资料luaL_ref)和某些预定义值使用。因此,整数键不得用于其他目的。

当您创建新的Lua状态时,其注册表会附带一些预定义的值。这些预定义值使用定义为常量的整数键索引lua.h。定义了以下常量:

LUA_RIDX_MAINTHREAD:在此索引处,注册表具有状态的主线程。(主线程是与州一起创建的线程。)
LUA_RIDX_GLOBALS:在此索引处,注册表具有全局环境。
4.6 - C中的错误处理
在内部,Lua使用C longjmp工具来处理错误。(如果你将它编译为C ++,Lua将使用异常; LUAI_THROW在源代码中搜索详细信息。)当Lua面临任何错误(例如内存分配错误或类型错误)时,它会引发错误; 也就是说,它会跳远。一个受保护的环境使用setjmp 设置一个恢复点; 任何错误都会跳转到最近的活动恢复点。

在C函数内部,您可以通过调用引发错误lua_error。

API中的大多数函数都会引发错误,例如由于内存分配错误。每个函数的文档都指出它是否会引发错误。

如果在任何受保护的环境之外发生错误,Lua会调用一个panic函数(请参阅参考资料lua_atpanic)然后调用abort,从而退出宿主应用程序。您的恐慌功能可以通过永不返回来避免这种退出(例如,在Lua外部进行长跳转到您自己的恢复点)。

顾名思义,恐慌功能是最后的手段。程序应该避免它。作为一般规则,当Lua使用Lua状态调用C函数时,它可以在Lua状态上执行任何操作,因为它应该已经受到保护。但是,当C代码在其他Lua状态上运行时(例如,函数的Lua参数,存储在注册表中的Lua状态或结果lua_newthread),它应该仅在不会引发错误的API调用中使用它们。

panic函数就像是一个消息处理程序一样运行(参见§2.3); 特别是,错误对象位于堆栈的顶部。但是,无法保证堆栈空间。要在堆栈上推送任何内容,恐慌功能必须首先检查可用空间(参见§4.2)。

4.7 - 处理C中的收益率
在内部,Lua使用C longjmp工具来产生协程。因此,如果C函数foo调用API函数并且此API函数通过调用另一个产生的函数直接或间接地产生,则Lua不能再返回foo,因为longjmp它从C堆栈中移除了它的帧。

为了避免这样的问题,提出的Lua每当它试图跨越API调用来产生,除了三个功能错误: lua_yieldk,lua_callk,和lua_pcallk。所有这些函数都接收一个continuation函数 (作为一个名为的参数k),以便在yield之后继续执行。

我们需要设置一些术语来解释延续。我们有一个从Lua调用的C函数,我们将调用原始函数。然后,这个原始函数调用C API中的三个函数之一,我们将调用callee函数,然后生成当前线程。(这可能发生在被调用函数是lua_yieldk,或者当被调用函数是lua_callk或者lua_pcallk 并且由它们调用的函数产生时)。

假设正在运行的线程在执行被调用函数时产生。线程恢复后,最终将完成运行被调用函数。但是,被调用函数无法返回到原始函数,因为它在C堆栈中的帧被yield损坏。相反,Lua调用一个continuation函数,它作为被调用函数的参数给出。顾名思义,延续函数应该继续原始函数的任务。

作为说明,请考虑以下功能:

int original_function(lua_State * L){
... / *代码1 * /
status = lua_pcall(L,n,m,h); / *调用Lua * /
... / *代码2 * /
}
现在我们想让Lua代码运行lua_pcall得到。首先,我们可以像这样重写我们的函数:

int k(lua_State * L,int status,lua_KContext ctx){
... / *代码2 * /
}

int original_function(lua_State * L){
... / *代码1 * /
返回k(L,lua_pcall(L,n,m,h),ctx);
}
在上面的代码中,new函数k是一个 continuation函数(带有类型lua_KFunction),它应该完成调用后原始函数所做的所有工作lua_pcall。现在,我们必须通知Lua,k如果执行的Lua代码lua_pcall以某种方式被中断(错误或让步),它必须调用,所以我们在这里重写代码,替换lua_pcall为lua_pcallk:

int original_function(lua_State * L){
... / *代码1 * /
返回k(L,lua_pcallk(L,n,m,h,ctx2,k),ctx1);
}
注意对continuation的外部显式调用:Lua仅在需要时调用continuation,即出现错误或在yield之后恢复。如果被调用函数正常返回而没有屈服, lua_pcallk(和lua_callk)也将正常返回。(当然,在这种情况下,您可以直接在原始函数内部执行相同的工作,而不是调用延续。)

除了Lua状态之外,continuation函数还有另外两个参数:调用的最终状态加上ctx最初传递给的上下文值()lua_pcallk。(Lua不使用此上下文值;它只将此值从原始函数传递给continuation函数。)因为lua_pcallk,状态是将返回的相同值lua_pcallk,除了它是LUA_YIELD在yield之后执行时(而不是的LUA_OK)。对于lua_yieldk和lua_callk,状态总是LUA_YIELD在Lua调用延续时。(对于这两个函数,Lua不会在出现错误时调用continuation,因为它们不会处理错误。)同样,在使用时lua_callk,应该使用LUA_OKstatus作为continuation函数。(对于lua_yieldk直接调用continuation函数没有多大意义,因为lua_yieldk通常不会返回。)

Lua将延续函数视为原始函数。continuation函数从原始函数接收相同的Lua堆栈,处于与被调用函数返回时相同的状态。(例如,在lua_callk函数及其参数从堆栈中删除并替换为调用的结果之后)。它也具有相同的upvalues。无论它返回什么都由Lua处理,就好像它是原始函数的返回一样。

4.8 - 功能和类型
这里我们按字母顺序列出C API中的所有函数和类型。每个函数都有一个这样的指标: [ - o,+ p,x ]

第一个字段o是函数从堆栈弹出的元素数量。第二个字段p是函数推入堆栈的元素数量。(任何函数在弹出其参数后总是推送其结果。)表单中的字段x|y表示函数可以推送(或弹出) x或y元素,具体取决于具体情况; 询问标记' ?'意味着我们不能通过仅查看其参数来知道函数弹出/推送的元素数量(例如,它们可能取决于堆栈上的内容)。第三个字段x告诉函数是否可能引发错误:' -'表示函数从不引发任何错误; ' m'表示该函数可能会引发内存__gc不足错误和运行metamethod的错误; “e'表示函数可能引发任何错误(它可以直接或通过元方法运行任意Lua代码); ' v'表示该函数可能故意引发错误。

lua_absindex
[-0,+ 0, - ]
int lua_absindex(lua_State * L,int idx);
将可接受的索引idx 转换为等效的绝对索引(即,不依赖于堆栈顶部的索引)。

lua_Alloc
typedef void *(* lua_Alloc)(void * ud,
void * ptr,
size_t osize,
size_t nsize);
Lua使用的内存分配函数的类型。分配器功能必须提供类似realloc但不完全相同的功能。它的参数是 ud,传递给一个不透明的指针lua_newstate; ptr,指向正在分配/重新分配/释放的块的指针; osize,块的原始大小或关于正在分配的内容的一些代码; 并且nsize,块的新大小。

如果ptr不是NULL, osize则指向块的大小ptr,即分配或重新分配时给定的大小。

如果ptr是NULL, osize编码Lua是分配类型的对象。 osize是任何的 LUA_TSTRING,LUA_TTABLE,LUA_TFUNCTION, LUA_TUSERDATA,或LUA_TTHREAD当(且仅当)Lua是创建该类型的新对象。什么osize是其他值,Lua正在为其他东西分配内存。

Lua从分配器函数中假定以下行为:

当nsize为零时,分配器必须表现得像free 并返回NULL。

当nsize不为零时,分配器必须表现得像realloc。NULL 当且仅当它不能满足请求时,分配器才返回。Lua假设分配器永远不会失败 osize >= nsize。

这是分配器功能的简单实现。它在辅助库中使用luaL_newstate。

static void * l_alloc(void * ud,void * ptr,size_t osize,
size_t nsize){
(空隙)UD; (空隙)osize; /* 不曾用过 */
if(nsize == 0){
免费(PTR);
返回NULL;
}
其他
return realloc(ptr,nsize);
}
请注意,标准C确保free(NULL)没有效果, realloc(NULL,size)并且相当于malloc(size)。此代码假定realloc缩小块时不会失败。(虽然标准C不能确保这种行为,但它似乎是一个安全的假设。)

lua_arith
[ - (2 | 1),+ 1,e ]
void lua_arith(lua_State * L,int op);
对堆栈顶部的两个值(或者在否定的情况下为一个值)执行算术或按位运算,顶部的值是第二个操作数,弹出这些值,并推送操作的结果。该函数遵循相应Lua运算符的语义(也就是说,它可以调用metamethods)。

值op必须是以下常量之一:

LUA_OPADD:执行加法(+)
LUA_OPSUB:执行减法(-)
LUA_OPMUL:执行乘法(*)
LUA_OPDIV:执行浮动除法(/)
LUA_OPIDIV:执行楼层划分(//)
LUA_OPMOD:执行modulo(%)
LUA_OPPOW:执行取幂(^)
LUA_OPUNM:执行数学否定(一元-)
LUA_OPBNOT:按位执行NOT(~)
LUA_OPBAND:执行按位AND(&)
LUA_OPBOR:执行按位OR(|)
LUA_OPBXOR:执行按位异或(~)
LUA_OPSHL:执行左移(<<)
LUA_OPSHR:执行右移(>>)
lua_atpanic
[-0,+ 0, - ]
lua_CFunction lua_atpanic(lua_State * L,lua_CFunction panicf);
设置新的恐慌功能并返回旧的功能(参见§4.6)。

lua_call
[ - (nargs + 1),+ nresults,e ]
void lua_call(lua_State * L,int nargs,int nresults);
调用一个函数。

要调用函数,必须使用以下协议:首先,要调用的函数被压入堆栈; 然后,函数的参数按直接顺序推送; 也就是说,首先推送第一个参数。最后你打电话lua_call; nargs是您推入堆栈的参数数量。调用函数时,所有参数和函数值都从堆栈中弹出。函数返回时,函数结果被压入堆栈。nresults除非nresults是,否则将结果数量调整为LUA_MULTRET。在这种情况下,推送该函数的所有结果; Lua注意返回的值适合堆栈空间,但它不能确保堆栈中有任何额外的空间。函数结果按直接顺序压入堆栈(第一个结果先被推送),因此在调用之后,最后一个结果位于堆栈顶部。

被调用函数内部的任何错误都会向上传播(带有a longjmp)。

以下示例显示了宿主程序如何执行与此Lua代码等效的操作:

a = f(“how”,tx,14)
这是在C:

lua_getglobal(L,“f”); / *函数被调用* /
lua_pushliteral(L,“how”); / *第一个参数* /
lua_getglobal(L,“t”); / *要索引的表* /
lua_getfield(L,-1,“x”); / *推送结果tx(2nd arg)* /
lua_remove(L,-2); / *从堆栈中删除't'* /
lua_pushinteger(L,14); / *第三个参数* /
lua_call(L,3,1); / *用3个参数和1个结果调用'f'* /
lua_setglobal(L,“a”); / *设置全局'a'* /
请注意,上面的代码是平衡的:在其末尾,堆栈恢复到其原始配置。这被认为是很好的编程实践。

lua_callk
[ - (nargs + 1),+ nresults,e ]
void lua_callk(lua_State * L,
int nargs,
结果,
lua_KContext ctx,
lua_KFunction k);
此函数的行为与此类似lua_call,但允许被调用的函数产生(参见§4.7)。

lua_CFunction
typedef int(* lua_CFunction)(lua_State * L);
输入C函数。

为了与Lua正确通信,C函数必须使用以下协议,该协议定义参数和结果的传递方式:C函数以直接顺序从其堆栈中的Lua接收其参数(首先推送第一个参数)。因此,当函数启动时, lua_gettop(L)返回函数接收的参数数量。第一个参数(如果有)在索引1处,其最后一个参数在索引处lua_gettop(L)。要将值返回到Lua,C函数只是按顺序将它们推入堆栈(首先推送第一个结果),然后返回结果数。Lua将正确地丢弃结果下方堆栈中的任何其他值。像Lua函数一样,Lua调用的C函数也可以返回许多结果。

例如,以下函数接收可变数量的数字参数并返回它们的平均值及其总和:

static int foo(lua_State * L){
int n = lua_gettop(L); / *参数数量* /
lua_Number sum = 0.0;
int i;
for(i = 1; i <= n; i ++){
if(!lua_isnumber(L,i)){
lua_pushliteral(L,“不正确的参数”);
lua_error(L);
}
sum + = lua_tonumber(L,i);
}
lua_pushnumber(L,sum / n); / *第一个结果* /
lua_pushnumber(L,sum); / *第二个结果* /
返回2; / *结果数量* /
}
lua_checkstack
[-0,+ 0, - ]
int lua_checkstack(lua_State * L,int n);
确保堆栈具有至少n额外插槽的空间(也就是说,您可以安全地将n值推入其中)。如果它无法满足请求,则返回false,因为它会导致堆栈大于固定的最大大小(通常至少有几千个元素),或者因为它无法为额外空间分配内存。这个函数永远不会缩小堆栈; 如果堆栈已经有额外插槽的空间,则保持不变。

lua_close
[-0,+ 0, - ]
void lua_close(lua_State * L);
销毁给定Lua状态中的所有对象(调用相应的垃圾收集元方法,如果有的话)并释放此状态使用的所有动态内存。在多个平台中,您可能不需要调用此函数,因为所有资源在宿主程序结束时自然释放。另一方面,创建多个状态的长时间运行的程序(例如守护进程或Web服务器)可能需要在不需要时立即关闭状态。

lua_compare
[-0,+ 0,e ]
int lua_compare(lua_State * L,int index1,int index2,int op);
比较两个Lua值。如果索引处的值index1满足op 与索引处的值进行比较时返回1 index2,则遵循相应Lua运算符的语义(即,它可以调用metamethods)。否则返回0.如果任何索引无效,则返回0。

值op必须是以下常量之一:

LUA_OPEQ:比较等于(==)
LUA_OPLT:比较小于(<)
LUA_OPLE:比较小于或等于(<=)
lua_concat
[-n,+ 1,e ]
void lua_concat(lua_State * L,int n);
连接n堆栈顶部的值,弹出它们,并将结果保留在顶部。如果n 为1,则结果是堆栈上的单个值(即函数不执行任何操作); 如果n为0,则结果为空字符串。连接是按照Lua的通常语义执行的(参见§3.4.6)。

lua_copy
[-0,+ 0, - ]
void lua_copy(lua_State * L,int fromidx,int toidx);
将index处的元素复制fromidx 到有效索引中toidx,替换该位置的值。其他位置的值不受影响。

lua_createtable
[-0,+ 1,m ]
void lua_createtable(lua_State * L,int narr,int nrec);
创建一个新的空表并将其推入堆栈。参数narr是表格将作为序列具有多少元素的提示; 参数nrec是表格将包含多少其他元素的提示。Lua可以使用这些提示为新表预分配内存。当您事先知道该表将包含多少元素时,此预分配对性能很有用。否则你可以使用该功能lua_newtable。

lua_dump
[-0,+ 0, - ]
int lua_dump(lua_State * L,
lua_Writer作家,
无效*数据,
int strip);
将函数转储为二进制块。在堆栈顶部接收Lua函数并生成一个二进制块,如果再次加载,则会产生与转储的函数等效的函数。当它生成块的一部分时, lua_dump调用函数writer(参见lua_Writer)用给定的data 来写它们。

如果strip为true,则二进制表示可能不包括有关该函数的所有调试信息,以节省空间。

返回的值是上次调用writer时返回的错误代码; 0表示没有错误。

此函数不会从堆栈中弹出Lua函数。

lua_error
[-1,+ 0,v ]
int lua_error(lua_State * L);
生成Lua错误,使用堆栈顶部的值作为错误对象。此函数执行长跳转,因此永远不会返回(请参阅参考资料luaL_error)。

lua_gc
[-0,+ 0,m ]
int lua_gc(lua_State * L,int what,int data);
控制垃圾收集器。

此函数根据参数的值执行多个任务what:

LUA_GCSTOP: 停止垃圾收集器。
LUA_GCRESTART: 重新启动垃圾收集器。
LUA_GCCOLLECT: 执行完整的垃圾收集周期。
LUA_GCCOUNT: 返回Lua使用的当前内存量(以KB为单位)。
LUA_GCCOUNTB: 返回Lua使用的当前内存字节数除以1024的余数。
LUA_GCSTEP: 执行垃圾收集的增量步骤。
LUA_GCSETPAUSE: 设置data为收集器暂停的新值(参见§2.5)并返回暂停的先前值。
LUA_GCSETSTEPMUL: 设置data为收集器的步长乘数的新值(参见§2.5)并返回步长乘数的先前值。
LUA_GCISRUNNING: 返回一个布尔值,告诉收集器是否正在运行(即未停止)。
有关这些选项的更多详细信息,请参阅collectgarbage。

lua_getallocf
[-0,+ 0, - ]
lua_Alloc lua_getallocf(lua_State * L,void ** ud);
返回给定状态的内存分配函数。如果ud不是NULL,则Lua存储在*ud设置memory-allocator函数时给出的不透明指针中。

lua_getfield
[-0,+ 1,e ]
int lua_getfield(lua_State * L,int index,const char * k);
将值推送到堆栈t[k],其中t是给定索引处的值。与Lua一样,此函数可能触发“索引”事件的元方法(参见§2.4)。

返回推送值的类型。

lua_getextraspace
[-0,+ 0, - ]
void * lua_getextraspace(lua_State * L);
返回指向与给定Lua状态关联的原始内存区域的指针。该应用程序可以将此区域用于任何目的; Lua不会将它用于任何事情。

每个新线程都使用主线程区域的副本初始化此区域。

默认情况下,此区域具有指向void的指针大小,但您可以为此区域重新编译具有不同大小的Lua。(参见LUA_EXTRASPACE在luaconf.h)。

lua_getglobal
[-0,+ 1,e ]
int lua_getglobal(lua_State * L,const char * name);
将全局值推入堆栈name。返回该值的类型。

lua_geti
[-0,+ 1,e ]
int lua_geti(lua_State * L,int index,lua_Integer i);
将值推送到堆栈t[i],其中t是给定索引处的值。与Lua一样,此函数可能触发“索引”事件的元方法(参见§2.4)。

返回推送值的类型。

lua_getmetatable
[-0,+(0 | 1), - ]
int lua_getmetatable(lua_State * L,int index);
如果给定索引处的值具有metatable,则该函数将该metatable推送到堆栈并返回1.否则,该函数返回0并且不会在堆栈上推送任何内容。

lua_gettable
[-1,+ 1,e ]
int lua_gettable(lua_State * L,int index);
将值推送到堆栈t[k],其中t是给定索引k处的值,并且是堆栈顶部的值。

此函数从堆栈中弹出键,将结果值推送到其位置。与Lua一样,此函数可能触发“索引”事件的元方法(参见§2.4)。

返回推送值的类型。

lua_gettop
[-0,+ 0, - ]
int lua_gettop(lua_State * L);
返回堆栈中顶部元素的索引。因为索引从1开始,所以此结果等于堆栈中的元素数量; 特别是,0表示空堆栈。

lua_getuservalue
[-0,+ 1, - ]
int lua_getuservalue(lua_State * L,int index);
将与给定索引处的完整用户数据关联的Lua值推入堆栈。

返回推送值的类型。

lua_insert
[-1,+ 1, - ]
void lua_insert(lua_State * L,int index);
将top元素移动到给定的有效索引中,将此索引上方的元素向上移动到开放空间。无法使用伪索引调用此函数,因为伪索引不是实际的堆栈位置。

lua_Integer
typedef ... lua_Integer;
Lua中的整数类型。

默认情况下,此类型是long long(通常为64位二进制补码整数),但可以更改为long或int (通常为32位二进制补码整数)。(参见LUA_INT_TYPE在luaconf.h)。

LUA还定义的常量 LUA_MININTEGER和LUA_MAXINTEGER,具有最小和适合于这种类型的最大值。

lua_isboolean
[-0,+ 0, - ]
int lua_isboolean(lua_State * L,int index);
如果给定索引处的值是布尔值,则返回1,否则返回0。

lua_iscfunction
[-0,+ 0, - ]
int lua_iscfunction(lua_State * L,int index);
如果给定索引处的值是C函数,则返回1,否则返回0。

lua_isfunction
[-0,+ 0, - ]
int lua_isfunction(lua_State * L,int index);
如果给定索引处的值是函数(C或Lua),则返回1,否则返回0。

lua_isinteger
[-0,+ 0, - ]
int lua_isinteger(lua_State * L,int index);
如果给定索引处的值是整数(即,该值是数字并表示为整数),则返回1,否则返回0。

lua_islightuserdata
[-0,+ 0, - ]
int lua_islightuserdata(lua_State * L,int index);
如果给定索引处的值是轻用户数据,则返回1,否则返回0。

lua_isnil
[-0,+ 0, - ]
int lua_isnil(lua_State * L,int index);
如果给定索引处的值为nil,则返回1,否则返回0。

lua_isnone
[-0,+ 0, - ]
int lua_isnone(lua_State * L,int index);
如果给定索引无效,则返回1,否则返回0。

lua_isnoneornil
[-0,+ 0, - ]
int lua_isnoneornil(lua_State * L,int index);
如果给定索引无效或此索引处的值为nil,则返回1,否则返回0。

lua_isnumber
[-0,+ 0, - ]
int lua_isnumber(lua_State * L,int index);
如果给定索引处的值是数字或可转换为数字的字符串,则返回1,否则返回0。

lua_isstring
[-0,+ 0, - ]
int lua_isstring(lua_State * L,int index);
如果给定索引处的值是字符串或数字(总是可转换为字符串),则返回1,否则返回0。

lua_istable
[-0,+ 0, - ]
int lua_istable(lua_State * L,int index);
如果给定索引处的值是表,则返回1,否则返回0。

lua_isthread
[-0,+ 0, - ]
int lua_isthread(lua_State * L,int index);
如果给定索引处的值是线程,则返回1,否则返回0。

lua_isuserdata
[-0,+ 0, - ]
int lua_isuserdata(lua_State * L,int index);
如果给定索引处的值是userdata(full或light),则返回1,否则返回0。

lua_isyieldable
[-0,+ 0, - ]
int lua_isyieldable(lua_State * L);
如果给定的协程可以产生,则返回1,否则返回0。

lua_KContext
typedef ... lua_KContext;
continuation-function上下文的类型。它必须是数字类型。此类型定义为何intptr_t 时intptr_t可用,以便它也可以存储指针。否则,它被定义为ptrdiff_t。

lua_KFunction
typedef int(* lua_KFunction)(lua_State * L,int status,lua_KContext ctx);
继续函数的类型(见§4.7)。

lua_len
[-0,+ 1,e ]
void lua_len(lua_State * L,int index);
返回给定索引处的值的长度。它等同#于Lua中的' '运算符(参见§3.4.7),并且可能触发“长度”事件的元方法(参见§2.4)。结果被推到堆栈上。

lua_load
[-0,+ 1, - ]
int lua_load(lua_State * L,
lua_Reader读者,
无效*数据,
const char * chunkname,
const char * mode);
加载Lua块而不运行它。如果没有错误, lua_load则将编译的块作为Lua函数推送到堆栈顶部。否则,它会推送错误消息。

返回值为lua_load:

LUA_OK:没有错误;
LUA_ERRSYNTAX: 预编译期间的语法错误;
LUA_ERRMEM: 内存分配(内存不足)错误;
LUA_ERRGCMM: 运行__gcmetamethod时出错。(此错误与正在加载的块无关。它由垃圾收集器生成。)
该lua_load函数使用用户提供的reader函数来读取块(请参阅参考资料lua_Reader)。该data参数是传递给阅读器功能的不透明值。

该chunkname参数给出了块的名称,该名称用于错误消息和调试信息(参见§4.9)。

lua_load自动检测块是文本还是二进制并相应加载(参见程序luac)。该字符串mode在函数中起作用load,另外一个NULL值等同于字符串“ bt”。

lua_load 在内部使用堆栈,因此读取器函数必须始终在返回时保持堆栈不被修改。

如果结果函数具有upvalues,则其第一个upvalue将设置为LUA_RIDX_GLOBALS注册表中存储在index处的全局环境的值(请参阅§4.5)。加载主块时,此upvalue将是_ENV变量(参见§2.2)。其他upvalues初始化为nil。

lua_newstate
[-0,+ 0, - ]
lua_State * lua_newstate(lua_Alloc f,void * ud);
创建以新的独立状态运行的新线程。返回NULL如果它不能创建线程或状态(由于内存不足)。参数f是分配器函数; Lua通过此函数为此状态进行所有内存分配(请参阅参考资料lua_Alloc)。第二个参数ud是Lua在每个调用中传递给分配器的不透明指针。

lua_newtable
[-0,+ 1,m ]
void lua_newtable(lua_State * L);
创建一个新的空表并将其推入堆栈。它相当于lua_createtable(L, 0, 0)。

lua_newthread
[-0,+ 1,m ]
lua_State * lua_newthread(lua_State * L);
创建一个新线程,将其推送到堆栈上,并返回一个指向lua_State该新线程的指针。此函数返回的新线程与原始线程共享其全局环境,但具有独立的执行堆栈。

没有显式函数来关闭或销毁线程。与任何Lua对象一样,线程可以进行垃圾收集。

lua_newuserdata
[-0,+ 1,m ]
void * lua_newuserdata(lua_State * L,size_t size);
此函数分配具有给定大小的新内存块,将具有块地址的新完整用户数据推入堆栈,并返回此地址。主程序可以*使用这个内存。

lua_next
[-1,+(2 | 0),e ]
int lua_next(lua_State * L,int index);
从堆栈中弹出一个键,并从给定索引处的表中推送一个键值对(给定键之后的“下一个”对)。如果表中没有更多元素,则lua_next返回0(并且不进行任何操作)。

典型的遍历如下所示:

/ * table在索引't'的堆栈中* /
lua_pushnil(L); / *第一把钥匙* /
while(lua_next(L,t)!= 0){
/ *使用'key'(在索引-2处)和'value'(在index -1处)* /
printf(“%s - %s \ n”,
lua_typename(L,lua_type(L,-2)),
lua_typename(L,lua_type(L,-1)));
/ *删除'value'; 保持下一次迭代的“关键”* /
lua_pop(L,1);
}
在遍历表时,不要lua_tolstring直接调用键,除非您知道该键实际上是一个字符串。回想一下,lua_tolstring可能会改变给定索引的值; 这会混淆下一次打电话lua_next。

有关next在遍历期间修改表的注意事项,请参阅函数。

lua_Number
typedef ... lua_Number;
Lua的浮子类型。

默认情况下,此类型为double,但可以更改为单个float或long double。(参见LUA_FLOAT_TYPE在luaconf.h)。

lua_numbertointeger
int lua_numbertointeger(lua_Number n,lua_Integer * p);
将Lua float转换为Lua整数。该宏假定n具有整数值。如果该值在Lua整数范围内,则将其转换为整数并分配给*p。宏导致一个布尔值,指示转换是否成功。(请注意,由于舍入,没有此宏,此范围测试可能很难正确执行。)

该宏可以多次评估其参数。

lua_pcall
[ - (nargs + 1),+(nresults | 1), - ]
int lua_pcall(lua_State * L,int nargs,int nresults,int msgh);
在保护模式下调用函数。

双方nargs并nresults具有相同的含义在lua_call。如果在通话期间没有错误,则 lua_pcall表现完全如此lua_call。但是,如果有任何错误, lua_pcall捕获它,在堆栈上推送单个值(错误对象),并返回错误代码。就像lua_call, lua_pcall总是从堆栈中删除函数及其参数。

如果msgh为0,则堆栈上返回的错误对象正是原始错误对象。否则,msgh是消息处理程序的堆栈索引 。(此索引不能是伪索引。)如果出现运行时错误,将使用错误对象调用此函数,并且其返回值将是堆栈返回的对象lua_pcall。

通常,消息处理程序用于向错误对象添加更多调试信息,例如堆栈回溯。返回后无法收集此类信息lua_pcall,因为此时堆栈已解除。

该lua_pcall函数返回以下常量之一(定义lua.h):

LUA_OK(0): 成功。
LUA_ERRRUN: 运行时错误。
LUA_ERRMEM: 内存分配错误。对于此类错误,Lua不会调用消息处理程序。
LUA_ERRERR: 运行消息处理程序时出错。
LUA_ERRGCMM: 运行__gcmetamethod时出错。对于这样的错误,Lua不会调用消息处理程序(因为这种错误通常与被调用的函数无关)。
lua_pcallk
[ - (nargs + 1),+(nresults | 1), - ]
int lua_pcallk(lua_State * L,
int nargs,
结果,
int msgh,
lua_KContext ctx,
lua_KFunction k);
此函数的行为与此类似lua_pcall,但允许被调用的函数产生(参见§4.7)。

lua_pop
[-n,+ 0, - ]
void lua_pop(lua_State * L,int n);
弹出n堆栈中的元素。

lua_pushboolean
[-0,+ 1, - ]
void lua_pushboolean(lua_State * L,int b);
将带有值的布尔值推b送到堆栈。

lua_pushcclosure
[-n,+ 1,m ]
void lua_pushcclosure(lua_State * L,lua_CFunction fn,int n);
将新的C闭包推入堆栈。

当创建C函数时,可以将一些值与它相关联,从而创建一个C闭包(见§4.4); 然后,只要调用它们,函数就可以访问这些值。要将值与C函数关联,首先必须将这些值压入堆栈(当存在多个值时,首先按下第一个值)。然后lua_pushcclosure 调用创建C函数并将其推送到堆栈上,并使用参数n告知将与函数关联的值。 lua_pushcclosure还会从堆栈中弹出这些值。

最大值为n255。

当n为零时,此函数创建一个轻C函数,它只是指向C函数的指针。在这种情况下,它永远不会引起内存错误。

lua_pushcfunction
[-0,+ 1, - ]
void lua_pushcfunction(lua_State * L,lua_CFunction f);
将C函数推入堆栈。该函数接收一个指向C函数的指针,并将一个Lua值推入堆栈,该类值function在调用时调用相应的C函数。

Lua可以调用的任何函数都必须遵循正确的协议才能接收其参数并返回其结果(请参阅参考资料lua_CFunction)。

lua_pushfstring
[-0,+ 1,e ]
const char * lua_pushfstring(lua_State * L,const char * fmt,...);
将格式化的字符串压入堆栈并返回指向此字符串的指针。它类似于ISO C函数sprintf,但有一些重要的区别:

您不必为结果分配空间:结果是Lua字符串,Lua负责内存分配(以及通过垃圾回收进行解除分配)。
转换说明符非常有限。没有标志,宽度或精度。转换说明符只能是' %%'(插入字符' %'),' %s'(插入一个以零结尾的字符串,没有大小限制),' %f'(插入一个lua_Number),' %I'(插入一个lua_Integer),' %p'(插入指针作为十六进制数字),' %d'(插入一个int),' %c'(插入int一个单字节字符)和' %U'(插入long int一个UTF-8字节序列)。
与其他推送功能不同,此功能会检查所需的堆栈空间,包括其结果的插槽。

lua_pushglobaltable
[-0,+ 1, - ]
void lua_pushglobaltable(lua_State * L);
将全局环境推送到堆栈。

lua_pushinteger
[-0,+ 1, - ]
void lua_pushinteger(lua_State * L,lua_Integer n);
将带有值的整数n推入堆栈。

lua_pushlightuserdata
[-0,+ 1, - ]
void lua_pushlightuserdata(lua_State * L,void * p);
将轻的用户数据推送到堆栈上。

Userdata表示Lua中的C值。甲光用户数据代表一个指针,一个void*。它是一个值(如数字):您不创建它,它没有单独的元表,也没有收集(因为它从未创建过)。轻用户数据等于具有相同C地址的“任何”轻用户数据。

lua_pushliteral
[-0,+ 1,m ]
const char * lua_pushliteral(lua_State * L,const char * s);
这个宏相当于lua_pushstring,但只应在使用时使用s文字字符串时使用。

lua_pushlstring
[-0,+ 1,m ]
const char * lua_pushlstring(lua_State * L,const char * s,size_t len);
按下指向的字符串 s大小len 推入堆栈。Lua生成(或重用)给定字符串的内部副本,因此s可以在函数返回后立即释放或重用内存。该字符串可以包含任何二进制数据,包括嵌入的零。

返回指向字符串内部副本的指针。

lua_pushnil
[-0,+ 1, - ]
void lua_pushnil(lua_State * L);
将nil值推入堆栈。

lua_pushnumber
[-0,+ 1, - ]
void lua_pushnumber(lua_State * L,lua_Number n);
将带有值的浮点数n推入堆栈。

lua_pushstring
[-0,+ 1,m ]
const char * lua_pushstring(lua_State * L,const char * s);
将指向的以零结尾的字符串压s 入堆栈。Lua生成(或重用)给定字符串的内部副本,因此s可以在函数返回后立即释放或重用内存。

返回指向字符串内部副本的指针。

如果s是NULL,推动nil并返回NULL。

lua_pushthread
[-0,+ 1, - ]
int lua_pushthread(lua_State * L);
将表示的线程L推入堆栈。如果此线程是其状态的主线程,则返回1。

lua_pushvalue
[-0,+ 1, - ]
void lua_pushvalue(lua_State * L,int index);
将给定索引处的元素副本推送到堆栈。

lua_pushvfstring
[-0,+ 1,m ]
const char * lua_pushvfstring(lua_State * L,
const char * fmt,
va_list argp);
相当于lua_pushfstring,除了它接收一个va_list 而不是可变数量的参数。

lua_rawequal
[-0,+ 0, - ]
int lua_rawequal(lua_State * L,int index1,int index2);
如果在索引的两个值,则返回1 index1和 index2是原始地等于(即,不调用__eq元方法)。否则返回0.如果任何索引无效,则返回0。

lua_rawget
[-1,+ 1, - ]
int lua_rawget(lua_State * L,int index);
类似于lua_gettable,但是进行原始访问(即没有metamethods)。

lua_rawgeti
[-0,+ 1, - ]
int lua_rawgeti(lua_State * L,int index,lua_Integer n);
将值推送到堆栈t[n],其中t是给定索引处的表。访问是原始的,也就是说,它不会调用元__index方法。

返回推送值的类型。

lua_rawgetp
[-0,+ 1, - ]
int lua_rawgetp(lua_State * L,int index,const void * p);
将值推送到堆栈t[k],其中t是给定索引处的表,并且 k指针p表示为轻用户数据。访问是原始的; 也就是说,它不会调用元__index方法。

返回推送值的类型。

lua_rawlen
[-0,+ 0, - ]
size_t lua_rawlen(lua_State * L,int index);
返回给定索引处的值的原始“length”:对于字符串,这是字符串长度; 对于表,这是长度运算符(' #')的结果,没有metamethods; 对于userdata,这是为userdata分配的内存块的大小; 对于其他值,它为0。

lua_rawset
[-2,+ 0,m ]
void lua_rawset(lua_State * L,int index);
类似于lua_settable,但是进行原始分配(即没有metamethods)。

lua_rawseti
[-1,+ 0,m ]
void lua_rawseti(lua_State * L,int index,lua_Integer i);
是等价的t[i] = v,其中t是给定索引处的表,并且v是堆栈顶部的值。

此函数弹出堆栈中的值。赋值是原始的,也就是说,它不会调用元__newindex方法。

lua_rawsetp
[-1,+ 0,m ]
void lua_rawsetp(lua_State * L,int index,const void * p);
相应于,给定索引处的表的t[p] = v位置t是否 p被编码为轻用户数据,并且v是堆栈顶部的值。

此函数弹出堆栈中的值。赋值是原始的,也就是说,它不会调用__newindexmetamethod。

lua_Reader
typedef const char *(* lua_Reader)(lua_State * L,
无效*数据,
size_t * size);
读者使用的功能lua_load。每当它需要另一块块时, lua_load调用读者,传递其data参数。读者必须使用新块的块返回指向内存块的指针并设置size为块大小。块必须存在,直到再次调用reader函数。要发出块的结束信号,读卡器必须返回NULL或设置size为零。读取器功能可以返回任何大于零的大小的片段。

lua_register
[-0,+ 0,e ]
void lua_register(lua_State * L,const char * name,lua_CFunction f);
将C函数设置f为全局的新值name。它被定义为一个宏:

#define lua_register(L,n,f)\
(lua_pushcfunction(L,f),lua_setglobal(L,n))
lua_remove
[-1,+ 0, - ]
void lua_remove(lua_State * L,int index);
移除给定有效索引处的元素,向下移动此索引上方的元素以填补空白。无法使用伪索引调用此函数,因为伪索引不是实际的堆栈位置。

lua_replace
[-1,+ 0, - ]
void lua_replace(lua_State * L,int index);
将顶部元素移动到给定的有效索引中而不移动任何元素(因此替换该给定索引处的值),然后弹出顶部元素。

lua_resume
[ - ?,+?, - ]
int lua_resume(lua_State * L,lua_State * from,int nargs);
在给定的线程中启动并恢复协程L。

要启动协程,你可以将主函数加上任何参数推送到线程堆栈; 然后你打电话lua_resume,nargs作为参数的数量。当协同程序暂停或完成其执行时,此调用将返回。返回时,堆栈包含传递给的lua_yield所有值,或者包含body函数返回的所有值。 如果协程生成,如果协程完成执行没有错误,则lua_resume返回; LUA_YIELD如果 LUA_OK出现错误,则返回错误代码(请参阅参考资料lua_pcall)。

如果出现错误,堆栈不会被解除,因此您可以在其上使用调试API。错误对象位于堆栈顶部。

要恢复一个协同程序,你从最后一个中删除任何结果lua_yield,只在其堆栈上放置要作为结果传递的值yield,然后调用lua_resume。

该参数from表示正在恢复的协同程序L。如果没有这样的协程,则此参数可以NULL。

lua_rotate
[-0,+ 0, - ]
void lua_rotate(lua_State * L,int idx,int n);
在有效索引idx 和堆栈顶部之间旋转堆栈元素。元件n在顶部方向上旋转的位置为正n,或者-n在底部的方向上的位置为负的n。绝对值n不得大于正在旋转的切片的大小。无法使用伪索引调用此函数,因为伪索引不是实际的堆栈位置。

lua_setallocf
[-0,+ 0, - ]
void lua_setallocf(lua_State * L,lua_Alloc f,void * ud);
将给定状态的分配器功能更改为f 用户数据ud。

lua_setfield
[-1,+ 0,e ]
void lua_setfield(lua_State * L,int index,const char * k);
是等价于t[k] = v,其中t是给定索引v处的值,是堆栈顶部的值。

此函数弹出堆栈中的值。与Lua一样,此函数可能触发“newindex”事件的元方法(参见§2.4)。

lua_setglobal
[-1,+ 0,e ]
void lua_setglobal(lua_State * L,const char * name);
从堆栈中弹出一个值并将其设置为全局的新值name。

lua_seti
[-1,+ 0,e ]
void lua_seti(lua_State * L,int index,lua_Integer n);
是等价于t[n] = v,其中t是给定索引v处的值,是堆栈顶部的值。

此函数弹出堆栈中的值。与Lua一样,此函数可能触发“newindex”事件的元方法(参见§2.4)。

lua_setmetatable
[-1,+ 0, - ]
void lua_setmetatable(lua_State * L,int index);
从堆栈中弹出一个表,并将其设置为给定索引处的值的新元表。

lua_settable
[-2,+ 0,e ]
void lua_settable(lua_State * L,int index);
等价于t[k] = v,t给定索引 v处的值是否为堆栈顶部k的值,并且是低于顶部的值。

此函数会弹出堆栈中的键和值。与Lua一样,此函数可能触发“newindex”事件的元方法(参见§2.4)。

lua_settop
[ - ?,+?, - ]
void lua_settop(lua_State * L,int index);
接受任何索引或0,并将堆栈顶部设置为此索引。如果新顶部大于旧顶部,则新元素将填充为nil。如果index为0,则删除所有堆栈元素。

lua_setuservalue
[-1,+ 0, - ]
void lua_setuservalue(lua_State * L,int index);
从堆栈中弹出一个值,并将其设置为与给定索引处的完整用户数据关联的新值。

lua_State
typedef struct lua_State lua_State;
一个不透明的结构,指向一个线程并间接(通过线程)指向Lua解释器的整个状态。Lua库是完全可重入的:它没有全局变量。可通过此结构访问有关州的所有信息。

必须将指向此结构的指针作为库中每个函数的第一个参数传递,除了lua_newstate从头创建Lua状态。

lua_status
[-0,+ 0, - ]
int lua_status(lua_State * L);
返回线程的状态L。

LUA_OK对于正常线程, 状态可以是0(),如果线程完成lua_resume带有错误的a的执行,或者LUA_YIELD线程被挂起,则为错误代码。

您只能在具有状态的线程中调用函数LUA_OK。您可以恢复具有状态的线程LUA_OK (以启动新的协程)或LUA_YIELD (恢复协程)。

lua_stringtonumber
[-0,+ 1, - ]
size_t lua_stringtonumber(lua_State * L,const char * s);
将以零结尾的字符串s转换为数字,将该数字推入堆栈,并返回字符串的总大小,即其长度加1。根据Lua的词汇约定,转换可以产生整数或浮点数(见§3.1)。该字符串可以包含前导和尾随空格以及符号。如果字符串不是有效数字,则返回0并且不进行任何操作。(注意,结果可以用作布尔值,如果转换成功,则为true。)

lua_toboolean
[-0,+ 0, - ]
int lua_toboolean(lua_State * L,int index);
将给定索引处的Lua值转换为C布尔值(0或1)。像Lua中的所有测试一样,lua_toboolean对于任何不同于false和nil的 Lua值, 返回true ; 否则返回false。(如果只想接受实际的布尔值,请使用lua_isboolean测试值的类型。)

lua_tocfunction
[-0,+ 0, - ]
lua_CFunction lua_tocfunction(lua_State * L,int index);
将给定索引处的值转换为C函数。该值必须是C函数; 否则,返回NULL。

lua_tointeger
[-0,+ 0, - ]
lua_Integer lua_tointeger(lua_State * L,int index);
相当于lua_tointegerx用isnum等于NULL。

lua_tointegerx
[-0,+ 0, - ]
lua_Integer lua_tointegerx(lua_State * L,int index,int * isnum);
将给定索引处的Lua值转换为有符号整数类型lua_Integer。Lua值必须是整数,或者可以转换为整数的数字或字符串(参见§3.4.3); 否则,lua_tointegerx返回0。

如果isnum不是NULL,则为其指示对象分配一个布尔值,指示操作是否成功。

lua_tolstring
[-0,+ 0,m ]
const char * lua_tolstring(lua_State * L,int index,size_t * len);
将给定索引处的Lua值转换为C字符串。如果len不是NULL,则设置*len字符串长度。Lua值必须是字符串或数字; 否则,函数返回NULL。如果值是数字,则lua_tolstring还将 堆栈中的实际值更改为字符串。(在表遍历期间应用于键lua_next 时,此更改会混淆lua_tolstring。)

lua_tolstring返回指向Lua状态内的字符串的指针。此字符串\0在其最后一个字符之后始终为零(' ')(如在C中),但在其正文中可以包含其他零。

因为Lua具有垃圾收集功能,所以无法保证返回的指针lua_tolstring 在从堆栈中删除相应的Lua值后才有效。

lua_tonumber
[-0,+ 0, - ]
lua_Number lua_tonumber(lua_State * L,int index);
相当于lua_tonumberx用isnum等于NULL。

lua_tonumberx
[-0,+ 0, - ]
lua_Number lua_tonumberx(lua_State * L,int index,int * isnum);
将给定索引处的Lua值转换为C类型lua_Number(请参阅参考资料lua_Number)。Lua值必须是可转换为数字的数字或字符串(参见§3.4.3); 否则,lua_tonumberx返回0。

如果isnum不是NULL,则为其指示对象分配一个布尔值,指示操作是否成功。

lua_topointer
[-0,+ 0, - ]
const void * lua_topointer(lua_State * L,int index);
将给定索引处的值转换为通用C指针(void*)。值可以是userdata,表,线程或函数; 否则,lua_topointer返回NULL。不同的对象会给出不同的指针。无法将指针转换回原始值。

通常,此函数仅用于散列和调试信息。

lua_tostring
[-0,+ 0,m ]
const char * lua_tostring(lua_State * L,int index);
相当于lua_tolstring用len等于NULL。

lua_tothread
[-0,+ 0, - ]
lua_State * lua_tothread(lua_State * L,int index);
将给定索引处的值转换为Lua线程(表示为lua_State*)。该值必须是一个线程; 否则,函数返回NULL。

lua_touserdata
[-0,+ 0, - ]
void * lua_touserdata(lua_State * L,int index);
如果给定索引处的值是完整用户数据,则返回其块地址。如果值为light userdata,则返回其指针。否则,返回NULL。

lua_type
[-0,+ 0, - ]
int lua_type(lua_State * L,int index);
返回给定有效索引中的值的类型,或者返回LUA_TNONE无效(但可接受)索引的值。返回的类型lua_type是通过在定义的以下常量编码lua.h: LUA_TNIL(0), , , LUA_TNUMBER, LUA_TBOOLEAN, LUA_TSTRING, , LUA_TTABLE , 和 。 LUA_TFUNCTIONLUA_TUSERDATALUA_TTHREADLUA_TLIGHTUSERDATA

lua_typename
[-0,+ 0, - ]
const char * lua_typename(lua_State * L,int tp);
返回由值编码的类型的名称,该值tp必须是返回的值之一lua_type。

lua_Unsigned
typedef ... lua_Unsigned;
未签名的版本lua_Integer。

lua_upvalueindex
[-0,+ 0, - ]
int lua_upvalueindex(int i);
返回表示i正在运行的函数的第 - 个up值的伪索引(参见§4.4)。

lua_version
[-0,+ 0, - ]
const lua_Number * lua_version(lua_State * L);
返回存储在Lua核心中的版本号(C静态变量)的地址。使用valid调用时lua_State,返回用于创建该状态的版本的地址。调用时NULL,返回运行调用的版本的地址。

lua_Writer
typedef int(* lua_Writer)(lua_State * L,
const void * p,
size_t sz,
void * ud);
使用的writer函数的类型lua_dump。每次它生成另一块块时, lua_dump调用writer,传递缓冲区以写入(p),它的size(sz)和data提供给的参数lua_dump。

编写器返回错误代码:0表示没有错误; 任何其他值意味着错误并停止lua_dump再次调用编写器。

lua_xmove
[ - ?,+?, - ]
void lua_xmove(lua_State * from,lua_State * to,int n);
在相同状态的不同线程之间交换值。

此函数n从堆栈中弹出值from,并将它们推送到堆栈中to。

lua_yield
[ - ?,+?,e ]
int lua_yield(lua_State * L,int nresults);
此函数相当于lua_yieldk,但没有延续(参见§4.7)。因此,当线程恢复时,它继续调用函数调用的函数lua_yield。

lua_yieldk
[ - ?,+?,e ]
int lua_yieldk(lua_State * L,
结果,
lua_KContext ctx,
lua_KFunction k);
产生一个协程(线程)。

当C函数调用时lua_yieldk,正在运行的协同程序暂停其执行,并且lua_resume对该协程的调用返回。该参数nresults是堆栈中将作为结果传递给的值的数量lua_resume。

当协程再次恢复时,Lua调用给定的continuation函数k继续执行产生的C函数(参见§4.7)。此延续函数从前一个函数接收相同的堆栈,并n删除结果并替换为传递给的参数lua_resume。此外,continuation函数接收ctx 传递给的值lua_yieldk。

通常,此功能不会返回; 当协程最终恢复时,它继续执行继续功能。但是,有一种特殊情况,即从行内部或计数钩子中调用此函数时(参见§4.9)。在这种情况下,lua_yieldk应该调用没有延续(可能是以形式lua_yield)并且没有结果,并且钩子应该在调用后立即返回。Lua会产生并且,当协程再次恢复时,它将继续正常执行触发钩子的(Lua)函数。

如果从具有挂起C调用且没有连续函数的线程调用它,或者从未在恢复(例如,主线程)内运行的线程调用它,则此函数可能引发错误。

4.9 - 调试接口
Lua没有内置的调试工具。相反,它通过函数和钩子提供了一个特殊的接口。该接口允许构建不同类型的调试器,分析器和其他需要来自解释器的“内部信息”的工具。

lua_Debug
typedef struct lua_Debug {
int事件;
const char * name; / *(n)* /
const char * namewhat; / *(n)* /
const char * what; / *(S)* /
const char * source; / *(S)* /
int currentline; / *(l)* /
int linedefined; / *(S)* /
int lastlinedefined; / *(S)* /
unsigned char nups; / *(u)upvalues数量* /
unsigned char nparams; / *(u)参数数量* /
char isvararg; / *(u)* /
char istailcall; / *(t)* /
char short_src [LUA_IDSIZE]; / *(S)* /
/ *私人部分* /
其他领域
} lua_Debug;
用于携带关于功能或激活记录的不同信息的结构。 lua_getstack仅填充此结构的私有部分,供以后使用。要填写lua_Debug有用信息的其他字段,请致电lua_getinfo。

这些领域lua_Debug具有以下含义:

source: 创建函数的块的名称。如果source以' @' 开头,则表示该函数是在文件名中跟随' @' 的文件中定义的。如果source以' =' 开头,则其内容的其余部分以依赖于用户的方式描述源。否则,函数在字符串中定义,其中 source是该字符串。
short_src:source用于错误消息 的“可打印”版本。
linedefined: 函数定义开始的行号。
lastlinedefined: 函数定义结束的行号。
what:"Lua"如果函数是Lua函数 的字符串, "C"如果它是C函数, "main"如果它是块的主要部分。
currentline: 给定函数执行的当前行。如果没有可用的行信息, currentline则设置为-1。
name: 给定函数的合理名称。因为Lua中的函数是一等值,所以它们没有固定的名称:某些函数可以是多个全局变量的值,而其他函数只能存储在表字段中。该lua_getinfo函数检查函数的调用方式以查找合适的名称。如果找不到名称,则name设置为NULL。
namewhat: 解释这个name领域。的值namewhat可以是 "global","local","method", "field","upvalue",或""(空字符串),根据功能如何被调用。(当没有其他选项似乎适用时,Lua使用空字符串。)
istailcall: 如果尾调用调用此函数调用,则为true。在这种情况下,此级别的调用者不在堆栈中。
nups: 函数的upvalues数。
nparams: 函数的固定参数数量(C函数总是0)。
isvararg: 如果函数是vararg函数,则为true(对于C函数,始终为true)。
lua_gethook
[-0,+ 0, - ]
lua_Hook lua_gethook(lua_State * L);
返回当前的钩子函数。

lua_gethookcount
[-0,+ 0, - ]
int lua_gethookcount(lua_State * L);
返回当前的挂钩计数。

lua_gethookmask
[-0,+ 0, - ]
int lua_gethookmask(lua_State * L);
返回当前的钩子掩码。

lua_getinfo
[ - (0 | 1),+(0 | 1 | 2),e ]
int lua_getinfo(lua_State * L,const char * what,lua_Debug * ar);
获取有关特定函数或函数调用的信息。

要获取有关函数调用的信息,该参数ar必须是有效的激活记录,该记录由先前调用lua_getstack或作为钩子的参数提供(请参阅参考资料lua_Hook)。

要获取有关函数的信息,请将其推入堆栈并what使用字符' >' 启动字符串。(在这种情况下, lua_getinfo从堆栈顶部弹出函数。)例如,要知道函数f定义在哪一行,您可以编写以下代码:

lua_Debug ar;
lua_getglobal(L,“f”); / *获取全局'f'* /
lua_getinfo(L,“> S”,&ar);
printf(“%d \ n”,ar.linedefined);
字符串中的每个字符都会what 选择ar要填充的结构的某些字段或要在堆栈上推送的值:

' n':填补领域name和namewhat;
' S“: 填补了领域source,short_src, linedefined,lastlinedefined,和what;
' l':填补领域currentline;
' t':填补领域istailcall;
' u“:填补了领域 nups,nparams以及isvararg;
' f': 将在给定级别运行的函数推入堆栈;
' L': 将一个表推入堆栈,其索引是函数上有效的行数。(有效的一行是带有一些相关代码的行,即可以放置断点的行。无效行包括空行和注释。)
如果此选项与选项' f' 一起提供,则在该函数后推送其表。

此函数在出错时返回0(例如,无效选项what)。

lua_getlocal
[-0,+(0 | 1), - ]
const char * lua_getlocal(lua_State * L,const lua_Debug * ar,int n);
获取有关给定激活记录或给定函数的局部变量的信息。

在第一种情况下,参数ar必须是有效的激活记录,该记录由先前调用lua_getstack或作为钩子的参数填充(请参阅参考资料lua_Hook)。索引n选择要检查的局部变量; debug.getlocal有关变量索引和名称的详细信息, 请参阅

lua_getlocal 将变量的值压入堆栈并返回其名称。

在第二种情况下,ar必须是NULL并且要检查的功能必须位于堆栈的顶部。在这种情况下,只有Lua函数的参数是可见的(因为没有关于哪些变量是活动的信息)并且没有值被推入堆栈。

NULL当索引大于活动局部变量的数量时, 返回(并且不进行任何操作)。

lua_getstack
[-0,+ 0, - ]
int lua_getstack(lua_State * L,int level,lua_Debug * ar);
获取有关解释器运行时堆栈的信息。

此函数lua_Debug使用 在给定级别执行的函数的激活记录的标识来填充结构的一部分。级别0是当前运行的函数,而级别n + 1是调用级别n的函数 (尾部调用除外,它不计入堆栈)。当没有错误时,lua_getstack返回1; 当以大于堆栈深度的级别调用时,它返回0。

lua_getupvalue
[-0,+(0 | 1), - ]
const char * lua_getupvalue(lua_State * L,int funcindex,int n);
获取有关n索引处闭包的第th个值的信息funcindex。它将upvalue的值压入堆栈并返回其名称。NULL当索引n大于upvalues的数量时,返回(并且不进行任何操作)。

对于C函数,此函数使用空字符串"" 作为所有upvalues的名称。(对于Lua函数,upvalues是函数使用的外部局部变量,因此包含在其闭包中。)

Upvalues没有特定的顺序,因为它们在整个函数中都是活动的。它们以任意顺序编号。

lua_Hook
typedef void(* lua_Hook)(lua_State * L,lua_Debug * ar);
用于调试挂钩函数的类型。

每当调用一个钩子时,它的ar参数都将其字段 event设置为触发钩子的特定事件。Lua中识别这些事件与以下常量: LUA_HOOKCALL,LUA_HOOKRET, LUA_HOOKTAILCALL,LUA_HOOKLINE,和LUA_HOOKCOUNT。此外,对于线事件,currentline也设置该字段。要获取任何其他字段的值ar,钩子必须调用lua_getinfo。

对于呼叫事件,event可以是LUA_HOOKCALL正常值,或者LUA_HOOKTAILCALL,对于尾部呼叫; 在这种情况下,将没有相应的返回事件。

当Lua正在运行一个钩子时,它会禁用对钩子的其他调用。因此,如果一个钩子回调Lua来执行一个函数或一个块,那么这个执行就会在没有任何钩子调用的情况下发生。

钩子函数不能延续,也就是说,他们不能打电话lua_yieldk, lua_pcallk或lua_callk与非空k。

钩子函数可以在以下条件下产生:只有count和line事件可以产生; 为了屈服,一个钩子函数必须lua_yield用nresults等于零的方式完成它的执行调用(也就是说,没有值)。

lua_sethook
[-0,+ 0, - ]
void lua_sethook(lua_State * L,lua_Hook f,int mask,int count);
设置调试挂钩功能。

参数f是钩子函数。 mask指定要在其事件的钩将被称为:它是由常量的位OR形成 LUA_MASKCALL, LUA_MASKRET, LUA_MASKLINE,和LUA_MASKCOUNT。该count参数仅在掩码包含时才有意义LUA_MASKCOUNT。对于每个事件,将调用钩子,如下所述:

调用钩子:在解释器调用函数时调用。在函数获取其参数之前,在Lua进入新函数之后调用该钩子。
当解释器从函数返回时,将调用返回钩子:在Lua离开函数之前调用该钩子。没有标准方法来访问函数返回的值。
当解释器即将开始执行新的代码行时,或者当它在代码中跳回(甚至到同一行)时,调用行钩子:。(此事件仅在Lua执行Lua函数时发生。)
count hook:在解释器执行每条count指令后调用 。(此事件仅在Lua执行Lua函数时发生。)
通过设置mask为零来禁用挂钩。

lua_setlocal
[ - (0 | 1),+ 0, - ]
const char * lua_setlocal(lua_State * L,const lua_Debug * ar,int n);
设置给定激活记录的局部变量的值。它将堆栈顶部的值分配给变量并返回其名称。它还会弹出堆栈中的值。

NULL当索引大于活动局部变量的数量时, 返回(并且不弹出任何内容)。

参数ar和n函数一样lua_getlocal。

lua_setupvalue
[ - (0 | 1),+ 0, - ]
const char * lua_setupvalue(lua_State * L,int funcindex,int n);
设置闭包的upvalue的值。它将堆栈顶部的值分配给upvalue并返回其名称。它还会弹出堆栈中的值。

NULL当索引n大于upvalues的数量时, 返回(并且不弹出任何内容)。

参数funcindex和n函数一样lua_getupvalue。

lua_upvalueid
[-0,+ 0, - ]
void * lua_upvalueid(lua_State * L,int funcindex,int n);
返回n 从索引处的闭包编号的upvalue的唯一标识符funcindex。

这些唯一标识符允许程序检查不同的闭包是否共享up值。共享upvalue的Lua闭包(即访问相同的外部局部变量)将为这些upvalue索引返回相同的id。

参数funcindex和n函数一样lua_getupvalue,但n不能大于upvalues的数量。

lua_upvaluejoin
[-0,+ 0, - ]
void lua_upvaluejoin(lua_State * L,int funcindex1,int n1,
int funcindex2,int n2);
使n1Lua中关闭索引个的upvalue funcindex1 指n2Lua中封个的upvalue的索引funcindex2。

5 - 辅助库
所述辅助库提供了几个方便的功能的接口下用的Lua。虽然基本API为C和Lua之间的所有交互提供了原始函数,但辅助库为某些常见任务提供了更高级别的函数。

辅助库中的所有函数和类型都在头文件中定义lauxlib.h并具有前缀luaL_。

辅助库中的所有函数都构建在基本API之上,因此它们不提供任何无法使用该API的功能。但是,使用辅助库可确保代码更加一致。

辅助库中的几个函数在内部使用一些额外的堆栈槽。当辅助库中的函数使用少于五个插槽时,它不会检查堆栈大小; 它只是假设有足够的插槽。

辅助库中的几个函数用于检查C函数参数。因为错误消息是为参数(例如,“ bad argument #1”)格式化的,所以不应将这些函数用于其他堆栈值。

luaL_check* 如果不满足检查,则 调用的函数始终会引发错误。

5.1 - 功能和类型
这里我们按字母顺序列出辅助库中的所有函数和类型。

luaL_addchar
[ - ?,+?,m ]
void luaL_addchar(luaL_Buffer * B,char c);
将字节添加c到缓冲区B (请参阅参考资料luaL_Buffer)。

luaL_addlstring
[ - ?,+?,m ]
void luaL_addlstring(luaL_Buffer * B,const char * s,size_t l);
将s带有length 的字符串添加l到缓冲区B (请参阅参考资料luaL_Buffer)。该字符串可以包含嵌入的零。

luaL_addsize
[ - ?,+?, - ]
void luaL_addsize(luaL_Buffer * B,size_t n);
添加到缓冲区B(请参阅luaL_Buffer)n先前复制到缓冲区的长度字符串(请参阅参考资料luaL_prepbuffer)。

luaL_addstring
[ - ?,+?,m ]
void luaL_addstring(luaL_Buffer * B,const char * s);
将指向的以零结尾的字符串添加s 到缓冲区B (请参阅参考资料luaL_Buffer)。

luaL_addvalue
[-1,+?,m ]
void luaL_addvalue(luaL_Buffer * B);
将堆栈顶部的值添加到缓冲区B (请参阅参考资料luaL_Buffer)。弹出价值。

这是字符串缓冲区上唯一可以(并且必须)使用堆栈上的额外元素调用的函数,这是要添加到缓冲区的值。

luaL_argcheck
[-0,+ 0,v ]
void luaL_argcheck(lua_State * L,
int cond,
int arg,
const char * extramsg);
检查是否cond属实。如果不是,则使用标准消息引发错误(请参阅参考资料luaL_argerror)。

luaL_argerror
[-0,+ 0,v ]
int luaL_argerror(lua_State * L,int arg,const char * extramsg);
arg 使用包含extramsg作为注释的标准消息 引发报告带有调用它的C函数的参数问题的错误:

坏参数#ARG为' funcname的 '(extramsg)
此功能永不返回。

luaL_Buffer
typedef struct luaL_Buffer luaL_Buffer;
输入字符串缓冲区。

字符串缓冲区允许C代码逐个构建Lua字符串。其使用模式如下:

首先声明一个b类型的变量luaL_Buffer。
然后通过调用初始化它luaL_buffinit(L, &b)。
然后将字符串片段添加到缓冲区中,调用任何luaL_add*函数。
通过电话结束luaL_pushresult(&b)。此调用将最终字符串保留在堆栈顶部。
如果事先知道结果字符串的总大小,可以像这样使用缓冲区:

首先声明一个b类型的变量luaL_Buffer。
然后初始化它并sz通过调用预先分配一个大小的空间luaL_buffinitsize(L, &b, sz)。
然后将字符串复制到该空间。
通过调用完成luaL_pushresultsize(&b, sz),其中sz将被复制到该空间中的结果字符串的总大小。
在其正常操作期间,字符串缓冲区使用可变数量的堆栈槽。因此,在使用缓冲区时,您不能假设您知道堆栈顶部的位置。只要该使用是平衡的,您就可以在连续调用缓冲区操作之间使用堆栈; 也就是说,当您调用缓冲区操作时,堆栈与前一个缓冲区操作之后的级别处于同一级别。(此规则的唯一例外是luaL_addvalue。)在luaL_pushresult初始化缓冲区后调用堆栈返回其级别,并在其顶部加上最后一个字符串。

luaL_buffinit
[-0,+ 0, - ]
void luaL_buffinit(lua_State * L,luaL_Buffer * B);
初始化缓冲区B。此功能不分配任何空间; 缓冲区必须声明为变量(请参阅参考资料luaL_Buffer)。

luaL_buffinitsize
[ - ?,+?,m ]
char * luaL_buffinitsize(lua_State * L,luaL_Buffer * B,size_t sz);
相当于序列 luaL_buffinit,luaL_prepbuffsize。

luaL_callmeta
[-0,+(0 | 1),e ]
int luaL_callmeta(lua_State * L,int obj,const char * e);
称之为元方法。

如果索引处的对象obj具有metatable并且此metatable具有字段e,则此函数将调用此字段作为其唯一参数传递对象。在这种情况下,此函数返回true并将调用返回的值推送到堆栈。如果没有metatable或没有metamethod,则此函数返回false(不在堆栈上推送任何值)。

luaL_checkany
[-0,+ 0,v ]
void luaL_checkany(lua_State * L,int arg);
检查函数是否在位置具有任何类型(包括nil)的参数arg。

luaL_checkinteger
[-0,+ 0,v ]
lua_Integer luaL_checkinteger(lua_State * L,int arg);
检查函数参数arg是否为整数(或可以转换为整数)并将此整数强制转换为a lua_Integer。

luaL_checklstring
[-0,+ 0,v ]
const char * luaL_checklstring(lua_State * L,int arg,size_t * l);
检查函数参数arg是否为字符串并返回该字符串; 如果l不NULL填充*l 字符串的长度。

此函数用于lua_tolstring获取其结果,因此该函数的所有转换和警告都适用于此处。

luaL_checknumber
[-0,+ 0,v ]
lua_Number luaL_checknumber(lua_State * L,int arg);
检查函数参数arg是否为数字并返回此数字。

luaL_checkoption
[-0,+ 0,v ]
int luaL_checkoption(lua_State * L,
int arg,
const char * def,
const char * const lst []);
检查函数参数arg是否为字符串,并在数组中搜索此字符串lst (必须以NULL结尾)。返回找到字符串的数组中的索引。如果参数不是字符串或者找不到字符串,则引发错误。

如果def不是NULL,则该函数def在没有参数arg或此参数为nil时用作默认值。

这是将字符串映射到C枚举的有用函数。(Lua库中通常的惯例是使用字符串而不是数字来选择选项。)

luaL_checkstack
[-0,+ 0,v ]
void luaL_checkstack(lua_State * L,int sz,const char * msg);
将堆栈大小增加到top + sz元素,如果堆栈无法增长到该大小,则会引发错误。 msg是一个附加到错误消息的NULL文本(或没有其他文本)。

luaL_checkstring
[-0,+ 0,v ]
const char * luaL_checkstring(lua_State * L,int arg);
检查函数参数arg是否为字符串并返回此字符串。

此函数用于lua_tolstring获取其结果,因此该函数的所有转换和警告都适用于此处。

luaL_checktype
[-0,+ 0,v ]
void luaL_checktype(lua_State * L,int arg,int t);
检查函数参数是否arg具有类型t。请参阅参见lua_type类型的编码t。

luaL_checkudata
[-0,+ 0,v ]
void * luaL_checkudata(lua_State * L,int arg,const char * tname);
检查函数参数是否arg是类型的用户数据tname(请参阅luaL_newmetatable参考资料)并返回用户数据地址(请参阅参考资料lua_touserdata)。

luaL_checkversion
[-0,+ 0,v ]
void luaL_checkversion(lua_State * L);
检查运行调用的核心,创建Lua状态的核心以及进行调用的代码是否都使用相同版本的Lua。还要检查运行调用的核心和创建Lua状态的核心是否使用相同的地址空间。

luaL_dofile
[-0,+?,e ]
int luaL_dofile(lua_State * L,const char * filename);
加载并运行给定的文件。它被定义为以下宏:

(luaL_loadfile(L,filename)|| lua_pcall(L,0,LUA_MULTRET,0))
如果没有错误,则返回false;如果出现错误,则返回true。

luaL_dostring
[-0,+?, - ]
int luaL_dostring(lua_State * L,const char * str);
加载并运行给定的字符串。它被定义为以下宏:

(luaL_loadstring(L,str)|| lua_pcall(L,0,LUA_MULTRET,0))
如果没有错误,则返回false;如果出现错误,则返回true。

luaL_error
[-0,+ 0,v ]
int luaL_error(lua_State * L,const char * fmt,...);
引发错误。错误消息格式由fmt 加上任何额外的参数给出,遵循相同的规则lua_pushfstring。如果此信息可用,它还会在消息开头添加文件名和发生错误的行号。

这个函数永远不会返回,但它是在C函数中使用它的习惯用法。 return luaL_error(args)

luaL_execresult
[-0,+ 3,m ]
int luaL_execresult(lua_State * L,int stat);
此函数为标准库(os.execute和io.close)中的过程相关函数生成返回值。

luaL_fileresult
[-0,+(1 | 3),m ]
int luaL_fileresult(lua_State * L,int stat,const char * fname);
该功能用于在标准库文件有关的功能(生成的返回值io.open,os.rename,file:seek等等)。

luaL_getmetafield
[-0,+(0 | 1),m ]
int luaL_getmetafield(lua_State * L,int obj,const char * e);
e从索引处的对象的元表 推送到堆栈的字段,obj并返回推送值的类型。如果对象没有metatable,或者metatable没有此字段,则不推送任何内容并返回LUA_TNIL。

luaL_getmetatable
[-0,+ 1,m ]
int luaL_getmetatable(lua_State * L,const char * tname);
将与tname 注册表中的名称关联的元表推送到堆栈(请参阅参考资料luaL_newmetatable)(如果没有与该名称关联的元表,则为nil)。返回推送值的类型。

luaL_getsubtable
[-0,+ 1,e ]
int luaL_getsubtable(lua_State * L,int idx,const char * fname);
确保值t[fname](其中t是index 处的值)idx是一个表,并将该表推送到堆栈上。如果找到前一个表,则返回true,如果创建新表,则返回false。

luaL_gsub
[-0,+ 1,m ]
const char * luaL_gsub(lua_State * L,
const char * s,
const char * p,
const char * r);
创建字符串的副本s替换字符串出现的任何p 以字符串r。将结果字符串压入堆栈并返回它。

luaL_len
[-0,+ 0,e ]
lua_Integer luaL_len(lua_State * L,int index);
返回给定索引处的值的“长度”作为数字; 它相当于#Lua中的' '运算符(见§3.4.7)。如果操作的结果不是整数,则引发错误。(这种情况只能通过元方法发生。)

luaL_loadbuffer
[-0,+ 1, - ]
int luaL_loadbuffer(lua_State * L,
const char * buff,
size_t sz,
const char * name);
相当于luaL_loadbufferx用mode等于NULL。

luaL_loadbufferx
[-0,+ 1, - ]
int luaL_loadbufferx(lua_State * L,
const char * buff,
size_t sz,
const char * name,
const char * mode);
将缓冲区加载为Lua块。此函数用于lua_load加载buff大小指向的缓冲区中的块sz。

此函数返回与之相同的结果lua_load。 name是块名称,用于调试信息和错误消息。该字符串mode在函数中起作用lua_load。

luaL_loadfile
[-0,+ 1,m ]
int luaL_loadfile(lua_State * L,const char * filename);
相当于luaL_loadfilex用mode等于NULL。

luaL_loadfilex
[-0,+ 1,m ]
int luaL_loadfilex(lua_State * L,const char * filename,
const char * mode);
将文件加载为Lua块。此函数用于lua_load在名为的文件中加载块filename。如果filename是NULL,则从标准输入加载。如果以a开头,则忽略文件中的第一行#。

该字符串mode在函数中起作用lua_load。

此函数返回与结果相同的结果lua_load,但它有LUA_ERRFILE 与文件相关的错误的额外错误代码(例如,它无法打开或读取文件)。

因为lua_load,这个函数只加载块; 它没有运行它。

luaL_loadstring
[-0,+ 1, - ]
int luaL_loadstring(lua_State * L,const char * s);
将字符串加载为Lua块。此函数用于lua_load将块加载到以零结尾的字符串中s。

此函数返回与之相同的结果lua_load。

此外lua_load,此功能仅加载块; 它没有运行它。

luaL_newlib
[-0,+ 1,m ]
void luaL_newlib(lua_State * L,const luaL_Reg l []);
创建一个新表并在列表中注册函数l。

它实现为以下宏:

(luaL_newlibtable(L,l),luaL_setfuncs(L,l,0))
数组l必须是实际数组,而不是指向它的指针。

luaL_newlibtable
[-0,+ 1,m ]
void luaL_newlibtable(lua_State * L,const luaL_Reg l []);
创建一个新的表,其大小已经过优化,可以存储数组中的所有条目l (但实际上并不存储它们)。它旨在与luaL_setfuncs (见luaL_newlib)一起使用。

它作为宏实现。数组l必须是实际数组,而不是指向它的指针。

luaL_newmetatable
[-0,+ 1,m ]
int luaL_newmetatable(lua_State * L,const char * tname);
如果注册表已经有钥匙tname,返回0。否则,创建一个新的表被用作用户数据一元表,增加了这个新表一对__name = tname,添加到注册表一对[tname] = new table,并返回1(入门__name使用通过一些错误报告功能。)

在这两种情况下,都会将与tname注册表中关联的最终值推送到堆栈。

luaL_newstate
[-0,+ 0, - ]
lua_State * luaL_newstate(void);
创建一个新的Lua状态。它lua_newstate使用基于标准C realloc函数的分配器进行调用,然后设置一个恐慌函数(参见§4.6),该函数在发生致命错误时将错误消息输出到标准错误输出。

返回新状态,或者NULL是否存在内存分配错误。

luaL_openlibs
[-0,+ 0,e ]
void luaL_openlibs(lua_State * L);
将所有标准Lua库打开到给定状态。

luaL_opt
[-0,+ 0,e ]
T luaL_opt(L,func,arg,dflt);
该宏定义如下:

(lua_isnoneornil(L,(arg))?(dflt):func(L,(arg)))
换句话说,如果参数arg为零或不存在,则宏将导致默认值dflt。否则,它会导致func 使用state L和参数index arg作为参数调用的结果。请注意,它dflt仅在需要时评估表达式。

luaL_optinteger
[-0,+ 0,v ]
lua_Integer luaL_optinteger(lua_State * L,
int arg,
lua_Integer d);
如果函数参数arg是整数(或可转换为整数),则返回此整数。如果此参数不存在或为零,则返回d。否则,会引发错误。

luaL_optlstring
[-0,+ 0,v ]
const char * luaL_optlstring(lua_State * L,
int arg,
const char * d,
size_t * l);
如果函数参数arg是字符串,则返回此字符串。如果此参数不存在或为零,则返回d。否则,会引发错误。

如果l不是NULL,则*l用结果的长度填充位置。如果结果是NULL (仅返回时可能d和d == NULL),它的长度被认为是零。

此函数用于lua_tolstring获取其结果,因此该函数的所有转换和警告都适用于此处。

luaL_optnumber
[-0,+ 0,v ]
lua_Number luaL_optnumber(lua_State * L,int arg,lua_Number d);
如果函数参数arg是数字,则返回此数字。如果此参数不存在或为零,则返回d。否则,会引发错误。

luaL_optstring
[-0,+ 0,v ]
const char * luaL_optstring(lua_State * L,
int arg,
const char * d);
如果函数参数arg是字符串,则返回此字符串。如果此参数不存在或为零,则返回d。否则,会引发错误。

luaL_prepbuffer
[ - ?,+?,m ]
char * luaL_prepbuffer(luaL_Buffer * B);
相当于luaL_prepbuffsize 预定义的大小LUAL_BUFFERSIZE。

luaL_prepbuffsize
[ - ?,+?,m ]
char * luaL_prepbuffsize(luaL_Buffer * B,size_t sz);
返回一个大小空间的地址sz ,您可以在其中复制要添加到缓冲区的字符串B (请参阅参考资料luaL_Buffer)。将字符串复制到此空间后,必须luaL_addsize使用字符串的大小调用 以将其实际添加到缓冲区。

luaL_pushresult
[ - ?,+ 1,m ]
void luaL_pushresult(luaL_Buffer * B);
完成缓冲区的使用,B将最终字符串留在堆栈顶部。

luaL_pushresultsize
[ - ?,+ 1,m ]
void luaL_pushresultsize(luaL_Buffer * B,size_t sz);
相当于序列luaL_addsize,luaL_pushresult。

luaL_ref
[-1,+ 0,m ]
int luaL_ref(lua_State * L,int t);
在索引的表中 创建并返回堆栈顶部对象的引用t(并弹出对象)。

引用是唯一的整数键。只要您不手动将整数键添加到表中t,就 luaL_ref可以确保它返回的键的唯一性。您可以r 通过调用检索引用引用的对象lua_rawgeti(L, t, r)。函数luaL_unref释放引用及其关联对象。

如果堆栈顶部的对象为nil,则 luaL_ref返回常量LUA_REFNIL。LUA_NOREF保证常量与返回的任何引用不同luaL_ref。

luaL_Reg
typedef struct luaL_Reg {
const char * name;
lua_CFunction func;
} luaL_Reg;
输入要注册的函数数组 luaL_setfuncs。 name是函数名称,func是指向函数的指针。任何数组都luaL_Reg必须以两个name和func都是的sentinel条目结束NULL。

luaL_requiref
[-0,+ 1,e ]
void luaL_requiref(lua_State * L,const char * modname,
lua_CFunction openf,int glb);
如果modname尚未出现package.loaded,则调用openf带有字符串modname作为参数的函数并将调用结果设置为package.loaded[modname],就像调用该函数一样require。

如果glb是,则还将模块存储到全局modname。

在堆栈上留下模块的副本。

luaL_setfuncs
[-nup,+ 0,m ]
void luaL_setfuncs(lua_State * L,const luaL_Reg * l,int nup);
将数组中的所有函数l (请参阅luaL_Reg)注册到堆栈顶部的表中(在可选的upvalues下面,请参阅下一个)。

当nup不为零时,创建所有函数共享nupupvalues,必须先将其推送到库表顶部的堆栈上。注册后,这些值将从堆栈中弹出。

luaL_setmetatable
[-0,+ 0, - ]
void luaL_setmetatable(lua_State * L,const char * tname);
将堆栈顶部对象的元表设置为与tname 注册表中的名称关联的元表(请参阅参考资料luaL_newmetatable)。

luaL_Stream
typedef struct luaL_Stream {
文件* f;
lua_CFunction closef;
} luaL_Stream;
文件句柄的标准表示,由标准I / O库使用。

文件句柄实现为完整的用户数据,并调用metatable LUA_FILEHANDLE (其中LUA_FILEHANDLE是一个带有实际metatable名称的宏)。metatable由I / O库创建(请参阅luaL_newmetatable)。

此userdata必须以结构开头luaL_Stream; 它可以包含此初始结构后的其他数据。字段f指向相应的C流(或者它可以NULL指示未完全创建的句柄)。字段closef指向Lua函数,当句柄关闭或收集时,将调用该函数来关闭流; 此函数接收文件句柄作为其唯一参数,并且必须返回true(如果成功)或nil加错误消息(如果出错)。一旦Lua调用此字段,它就会将字段值更改为NULL 表示句柄已关闭。

luaL_testudata
[-0,+ 0,m ]
void * luaL_testudata(lua_State * L,int arg,const char * tname);
此功能的作用类似于luaL_checkudata,但是,当测试失败时,它返回NULL而不是引发错误。

luaL_tolstring
[-0,+ 1,e ]
const char * luaL_tolstring(lua_State * L,int idx,size_t * len);
将给定索引处的任何Lua值转换为合理格式的C字符串。生成的字符串被压入堆栈并由函数返回。如果len不是NULL,该函数也设置*len字符串长度。

如果该值具有带__tostring字段的元表,则luaL_tolstring使用值作为参数调用相应的元方法,并将调用的结果用作其结果。

luaL_traceback
[-0,+ 1,m ]
void luaL_traceback(lua_State * L,lua_State * L1,const char * msg,
int level);
创建并推送堆栈的回溯L1。如果msg不是NULL,则在追溯开始时附加。该level参数指示启动回溯的级别。

luaL_typename
[-0,+ 0, - ]
const char * luaL_typename(lua_State * L,int index);
返回给定索引处的值类型的名称。

luaL_unref
[-0,+ 0, - ]
void luaL_unref(lua_State * L,int t,int ref);
ref从索引中的表中 释放引用t (请参阅参考资料luaL_ref)。该条目将从表中删除,以便可以收集引用的对象。该参考ref也被释放以便再次使用。

如果ref是LUA_NOREF或LUA_REFNIL, luaL_unref什么也不做。

luaL_where
[-0,+ 1,m ]
void luaL_where(lua_State * L,int lvl);
将一个字符串压入堆栈,以识别lvl调用堆栈中控件的当前位置。通常,此字符串具有以下格式:

chunkname:currentline:
级别0是运行功能,级别1是调用运行功能的功能等。

此函数用于构建错误消息的前缀。

6 - 标准图书馆
标准的Lua库提供了直接通过C API实现的有用功能。其中一些功能为语言提供基本服务(例如,type和getmetatable); 其他人提供对“外部”服务的访问(例如,I / O); 和其他可以在Lua本身实现,但是非常有用或具有值得在C中实现的关键性能要求(例如,table.sort)。

所有库都通过官方C API实现,并作为单独的C模块提供。目前,Lua拥有以下标准库:

基础图书馆(§6.1);
协程库(§6.2);
包库(§6.3);
字符串操作(第6.4节);
基本的UTF-8支持(§6.5);
表操作(第6.6节);
数学函数(§6.7)(sin,log等);
输入和输出(§6.8);
操作系统设施(§6.9);
调试设施(§6.10)。
除了基本库和包库之外,每个库都将其所有功能作为全局表的字段或其对象的方法提供。

要访问这些库,C主机程序应调用该luaL_openlibs函数,该函数将打开所有标准库。或者,宿主程序可以通过 luaL_requiref调用 luaopen_base(对于基本库), luaopen_package(对于包库), luaopen_coroutine(对于协程库), luaopen_string(对于字符串库), luaopen_utf8(对于UTF8库), luaopen_table(对于表库), luaopen_math(用于数学库), luaopen_io(用于I / O库), luaopen_os(用于操作系统库)和luaopen_debug(用于调试库)。这些函数在中声明lualib.h。

6.1 - 基本功能
基本库为Lua提供核心功能。如果您未在应用程序中包含此库,则应仔细检查是否需要为其某些工具提供实现。

assert (v [, message])
error如果其参数的v值为false(即,nil或false),则 调用; 否则,返回其所有参数。如果出错, message则为错误对象; 缺席时,默认为“ assertion failed!”

collectgarbage ([opt [, arg]])
此函数是垃圾收集器的通用接口。它根据第一个参数执行不同的功能opt:

“ collect”: 执行完整的垃圾收集周期。这是默认选项。
“ stop”: 停止自动执行垃圾收集器。收集器将仅在显式调用时运行,直到调用重新启动它。
“ restart”: 重新启动垃圾收集器的自动执行。
“ count”: 返回Lua使用的总内存(以KB为单位)。该值具有小数部分,因此它乘以1024得出Lua使用的确切字节数(溢出除外)。
“ step”: 执行垃圾收集步骤。步骤“大小”由arg。控制。如果值为零,则收集器将执行一个基本(不可分割)步骤。对于非零值,收集器将执行,就好像Lua已分配了该内存量(以KB为单位)。如果步骤完成收集周期,则返回true。
“ setpause”: 设置arg为收集器暂停的新值(参见§2.5)。返回暂停的先前值。
“ setstepmul”: 设置arg为收集器的步长乘数的新值(参见§2.5)。返回step的先前值。
“ isrunning”: 返回一个布尔值,告诉收集器是否正在运行(即未停止)。
dofile ([filename])
打开指定文件并将其内容作为Lua块执行。在不带参数的情况下调用时, dofile执行标准输入(stdin)的内容。返回块返回的所有值。如果出现错误,dofile请将错误传播给其调用方(即,dofile不以受保护模式运行)。
error (message [, level])
终止最后一个被调用的受保护函数,并message作为错误对象返回。功能error永不回归。
通常,error如果消息是字符串,则在消息开头添加有关错误位置的一些信息。该level参数指定如何得到错误的位置。对于级别1(默认值),错误位置是error调用函数的位置 。级别2将错误指向调用的函数的位置error; 等等。传递0级可避免向消息添加错误位置信息。

_G
保存全局环境的全局变量(不是函数)(参见§2.2)。Lua本身不使用这个变量; 改变其价值不会影响任何环境,反之亦然。
getmetatable (object)
如果object没有metatable,则返回nil。否则,如果对象的metatable具有__metatable字段,则返回关联的值。否则,返回给定对象的元表。

ipairs (t)
返回三个值(迭代器函数,表t和0)以便构造

对于i,v在ipairs(t)身体结束
将迭代键值对(1,t[1]),(2,t[2]),...,直到第一个零值。

load (chunk [, chunkname [, mode [, env]]])
加载一块。

如果chunk是字符串,则块是此字符串。如果chunk是一个函数, load重复调用它来获取块块。每次调用chunk必须返回一个与先前结果连接的字符串。返回空字符串,nil或no值表示块的结尾。

如果没有语法错误,则将编译的块作为函数返回; 否则,返回nil加上错误消息。

如果结果函数具有up值,则将第一个upvalue设置为env(如果给出该参数)的值,或者设置为全局环境的值。其他upvalues初始化为nil。(当你加载一个主块时,结果函数将总是只有一个upvalue,即_ENV变量(参见§2.2)。但是,当你加载一个从函数创建的二进制块(参见参考资料)时string.dump,生成的函数可以有一个任意数字upvalues。)所有upvalues都是新鲜的,也就是说,它们不与任何其他函数共享。

chunkname用作错误消息和调试信息的块名称(参见§4.9)。如果不存在,则默认为chunk,如果chunk是字符串,则为“ =(load)”。

字符串mode控制块是文本还是二进制(即预编译块)。它可以是字符串“ b”(仅二进制块),“ t”(仅文本块)或“ bt”(二进制和文本)。默认值为“ bt”。

Lua不检查二进制块的一致性。恶意制作的二进制块可能会使解释器崩溃。

loadfile ([filename [, mode [, env]]])
类似于load,但filename 如果没有给出文件名,则从文件或标准输入中获取块。

next (table [, index])
允许程序遍历表的所有字段。它的第一个参数是一个表,它的第二个参数是该表中的索引。 next返回表的下一个索引及其关联值。当使用nil作为其第二个参数调用时, next返回初始索引及其关联值。使用最后一个索引调用时,或者在空表中使用nil时, next返回nil。如果第二个参数不存在,则将其解释为nil。特别是,您可以使用next(t)检查表是否为空。

未指定索引的枚举顺序, 即使对于数字索引也是如此。(要遍历表中数字顺序,使用一个数值为)。

next如果在遍历期间将任何值分配给表中不存在的字段,则 行为未定义。但是,您可以修改现有字段。特别是,您可以清除现有字段。

pairs (t)
如果t有一个metamethod __pairs,请使用tas参数调用它,并返回调用的前三个结果。

否则,返回三个值:next函数,表t和nil,以便构造

对于k,v成对(t)做身体结束
将遍历表的所有键值对t。

有关next在遍历期间修改表的注意事项,请参阅函数。

pcall (f [, arg1, ···])
调用f在保护模式下使用给定参数运行。这意味着内部的任何错误 f都不会传播; 相反,pcall捕获错误并返回状态代码。它的第一个结果是状态代码(布尔值),如果调用成功且没有错误,则为true。在这种情况下,pcall也会在第一个结果之后返回调用的所有结果。如果有任何错误,则pcall返回false加上错误消息。

print (···)
接收任意数量的参数并将其值打印到stdout,使用该tostring函数将每个参数转换为字符串。 print不是用于格式化输出,而只是作为显示值的快速方法,例如用于调试。要完全控制输出,请使用string.format和io.write。
rawequal (v1, v2)
检查是否v1等于v2,而不调用__eqmetamethod。返回一个布尔值。
rawget (table, index)
获取实际值table[index],而不调用__indexmetamethod。 table必须是一张桌子; index可能是任何价值。
rawlen (v)
返回对象的长度,该对象v必须是表或字符串,而不调用元__len方法。返回一个整数。
rawset (table, index, value)
设置table[index]to 的实际值value,而不调用__newindexmetamethod。 table必须是一个表, index任何不同于nil和NaN的value值,以及任何Lua值。
此函数返回table。

select (index, ···)
如果index是数字,则返回参数号后面的所有参数index; 从末尾开始的负数索引(-1是最后一个参数)。否则,index必须是字符串"#",并select返回它收到的额外参数的总数。

setmetatable (table, metatable)
设置给定表的元表。(要从Lua代码更改其他类型的元表,必须使用调试库(第6.10节)。)如果metatable为nil,则删除给定表的元表。如果原始元表具有__metatable字段,则会引发错误。

此函数返回table。

tonumber (e [, base])
当使用no调用时base, tonumber尝试将其参数转换为数字。如果参数已经是数字或可转换为数字的字符串,则tonumber返回此数字; 否则,它返回零。

根据Lua的词汇约定,字符串的转换可以产生整数或浮点数(见§3.1)。(该字符串可能包含前导和尾随空格以及符号。)

当调用时base,则e必须是一个字符串,在该基数中被解释为整数。碱可以是2至36之间的任何整数,包括端值。在10以上的基数中,字母' A'(大写或小写)代表10,' B'代表11,依此类推,' Z'代表35.如果字符串e不是给定基数中的有效数字,则函数返回零。

tostring (v)
接收任何类型的值并将其转换为人类可读格式的字符串。(要完全控制数字的转换方式,请使用string.format。)
如果metatable v有一个__tostring字段,则tostring使用vas参数调用相应的值,并使用调用的结果作为结果。

type (v)
返回其唯一参数的类型,编码为字符串。该函数的可能结果是“ nil”(字符串,而不是值nil),“ number”,“ string”,“ boolean”,“ table”,“ function”,“ thread”和“ userdata”。
_VERSION
一个全局变量(不是函数),它包含一个包含正在运行的Lua版本的字符串。此变量的当前值为“ Lua 5.3”。

xpcall (f, msgh [, arg1, ···])
此函数类似于pcall,但它设置了一个新的消息处理程序msgh。

6.2 - 协同操作
该库包含操作协同程序的操作,这些操作来自表格内部coroutine。关于协同程序的一般描述见§2.6。

coroutine.create (f)
用身体创建一个新的协同程序f。 f必须是一个功能。返回这个新的协同程序,一个具有类型的对象"thread"。

coroutine.isyieldable ()
当正在运行的协程可以产生时返回true。

如果一个正在运行的协程不是主线程并且它不在非屈服C函数内,那么它是可以得到的。

coroutine.resume (co [, val1, ···])
开始或继续执行协同程序co。第一次你恢复一个协程,它开始运行它的身体。值val1,...作为参数传递给body函数。如果协程已经产生, resume重新启动它; 值val1,...作为yield的结果传递。

如果协同程序运行没有任何错误,则 resume返回true加上传递给的任何值yield (当协同程序产生时)或正文函数返回的任何值(当协程终止时)。如果有任何错误,则 resume返回false加上错误消息。

coroutine.running ()
返回正在运行的协同程序加上一个布尔值,当正在运行的协同程序是主程序时,返回true。

coroutine.status (co)
返回coroutine的状态co,作为字符串: "running",如果协同程序正在运行(即,它被调用status); "suspended"如果协程暂停通话yield,或者它还没有开始运行; "normal"如果协程是活动的但没有运行(也就是说,它已经恢复了另一个协同程序); 而"dead"如果协程完成其身体功能,或者如果它已停止错误。

coroutine.wrap (f)
用身体创建一个新的协同程序f。 f必须是一个功能。返回一个函数,每次调用它时都会恢复协同程序。传递给函数的任何参数都表现为额外的参数resume。返回与resume第一个布尔值相同的返回值。如果出现错误,则传播错误。

coroutine.yield (···)
暂停执行调用协程。任何参数yield都作为额外结果传递给resume。

6.3 - 模块
包库提供了在Lua中加载模块的基本工具。它直接在全局环境中导出一个函数: require。其他所有内容都在表格中导出package。

require (modname)
加载给定的模块。该函数首先查看package.loaded表以确定是否modname已加载。如果是,则require返回存储在的值package.loaded[modname]。否则,它会尝试为模块找到加载程序。

要查找装载程序,请 require按package.searchers顺序进行操作。通过更改此序列,我们可以更改require模块的查找方式。以下说明基于默认配置package.searchers。

第一次require查询package.preload[modname]。如果它有一个值,则该值(必须是函数)是加载器。否则require使用存储的路径搜索Lua加载程序package.path。如果失败,它将使用存储的路径搜索C加载程序package.cpath。如果这也失败了,它会尝试一个多功能的加载器(参见参考资料package.searchers)。

找到 require加载器后,使用两个参数调用加载器: modname一个额外的值取决于它如何获取加载器。(如果加载器来自文件,则此额外值是文件名。)如果加载器返回任何非零值, require则将返回的值赋给package.loaded[modname]。如果加载器未返回非零值且未向其分配任何值package.loaded[modname],则为此条目require指定true。无论如何,require返回最终值package.loaded[modname]。

如果加载或运行模块时出现任何错误,或者无法找到模块的任何加载程序,则会require引发错误。

package.config
描述包的一些编译时配置的字符串。该字符串是一系列行:

第一行是目录分隔符字符串。\对于Windows,默认为' ',/对于所有其他系统,默认为' ' 。
第二行是分隔路径中模板的字符。默认为' ;'。
第三行是标记模板中替换点的字符串。默认为' ?'。
第四行是一个字符串,在Windows中的路径中,由可执行文件的目录替换。默认为' !'。
第五行是在构建luaopen_函数名时忽略其后的所有文本的标记。默认为' -'。
package.cpath
require搜索C加载程序 所使用的路径。

Lua初始化C路径package.cpath的方式与初始化Lua路径的方式相同package.path,使用环境变量LUA_CPATH_5_3或环境变量LUA_CPATH,或者定义的默认路径luaconf.h。

package.loaded
用于require控制已加载哪些模块的表。当您需要模块modname且 package.loaded[modname]不是false时, require只需返回存储在那里的值。

这个变量只是对真实表的引用; 对此变量的赋值不会更改使用的表require。

package.loadlib (libname, funcname)
动态链接主机程序与C库libname。

如果funcname是“ *”,则它仅链接到库,使库导出的符号可用于其他动态链接库。否则,它funcname在库中查找函数并将此函数作为C函数返回。所以,funcname必须遵循lua_CFunction原型(见lua_CFunction)。

这是一个低级功能。它完全绕过了封装和模块系统。require与之不同,它不执行任何路径搜索,也不会自动添加扩展。 libname必须是C库的完整文件名,包括必要时的路径和扩展名。 funcname必须是C库导出的确切名称(可能取决于使用的C编译器和链接器)。

标准C不支持此功能。因此,它仅适用于某些平台(Windows,Linux,Mac OS X,Solaris,BSD以及支持该dlfcn标准的其他Unix系统)。

package.path
require搜索Lua加载程序 所使用的路径。

在启动时,如果未定义这些环境变量,Lua会使用环境变量LUA_PATH_5_3或环境变量的值LUA_PATH或使用定义的默认路径初始化此变量luaconf.h。;;环境变量值中的任何“ ”都将替换为默认路径。

package.preload
用于存储特定模块的加载器的表(请参阅参考资料require)。

这个变量只是对真实表的引用; 对此变量的赋值不会更改使用的表require。

package.searchers
用于require控制如何加载模块的表。

该表中的每个条目都是一个搜索器功能。在查找模块时, require按升序调用每个搜索器,模块名称(给定的参数require)作为其唯一参数。该函数可以返回另一个函数(模块加载器)加上一个将传递给该加载器的额外值,或一个字符串解释为什么它没有找到该模块(或者如果它没有什么可说的则为nil)。

Lua使用四个搜索器函数初始化此表。

第一个搜索者只是在package.preload表中寻找一个装载机 。

第二个搜索器使用存储在的路径查找加载器作为Lua库package.path。搜索按功能中的描述完成package.searchpath。

第三个搜索器使用变量给出的路径查找加载器作为C库package.cpath。同样,搜索按功能中的描述完成package.searchpath。例如,如果C路径是字符串

“./?.so;./?.dll;/usr/local/?/init.so”
对于模块搜索foo 将尝试打开这些文件./foo.so,./foo.dll以及/usr/local/foo/init.so以该顺序。一旦找到C库,该搜索者首先使用动态链接工具将应用程序与库链接。然后它尝试在库中找到一个C函数用作加载器。此C函数的名称是luaopen_与模块名称的副本连接的字符串“ ”,其中每个点由下划线替换。此外,如果模块名称具有连字符,则删除其后缀(并包括)第一个连字符后的后缀。例如,如果模块名称是a.b.c-v2.1,则函数名称将为luaopen_a_b_c。

第四个搜索者尝试一体化装载机。它在C路径中搜索库以获取给定模块的根名称。例如,在需要时a.b.c,它将搜索C库a。如果找到,它会查看子模块的打开函数; 在我们的例子中,那将是luaopen_a_b_c。使用此工具,程序包可以将多个C子模块打包到一个单独的库中,每个子模块保持其原始的打开功能。

除第一个(预加载)之外的所有搜索者都返回了找到模块的文件名的额外值,如返回的那样package.searchpath。第一个搜索者没有返回额外的值。

package.searchpath (name, path [, sep [, rep]])
搜索给定name的给定path。

路径是包含由分号分隔的一系列模板的字符串 。对于每个模板,该函数用一个副本替换模板中的每个询问标记(如果有的话),name 其中所有出现的sep (默认为一个点)被rep (系统的目录分隔符,默认情况下)替换,然后尝试打开生成的文件名。

例如,如果路径是字符串

“./?.lua;./?.lc;/usr/local/?/init.lua”
对于名称搜索foo.a 将尝试打开这些文件 ./foo/a.lua,./foo/a.lc以及 /usr/local/foo/a/init.lua以该顺序。

返回它可以在读取模式下打开的第一个文件的结果名称(在关闭文件之后),如果没有成功则返回nil加错误消息。(此错误消息列出了它尝试打开的所有文件名。)

6.4 - 字符串操作
该库提供了字符串操作的通用函数,例如查找和提取子字符串以及模式匹配。在Lua中索引字符串时,第一个字符位于位置1(而不是0,如在C中)。允许指数为负数,并从字符串末尾解释为向后索引。因此,最后一个字符位于-1,依此类推。

字符串库在表中提供其所有功能 string。它还为__index字段指向表的字符串设置元string表。因此,您可以在面向对象的样式中使用字符串函数。例如,string.byte(s,i) 可以写成s:byte(i)。

字符串库采用单字节字符编码。

string.byte (s [, i [, j]])
返回字符的内部数字代码s[i], s[i+1],... s[j]。默认值为i1; jis 的默认值i。这些指数按照相同的功能规则进行修正string.sub。
数字代码不一定是跨平台可移植的。

string.char (···)
接收零个或多个整数。返回一个长度等于参数个数的字符串,其中每个字符的内部数字代码等于其对应的参数。
数字代码不一定是跨平台可移植的。

string.dump (function [, strip])
返回包含给定函数的二进制表示(二进制块)的load字符串,以便稍后此字符串返回该函数的副本(但具有新的upvalues)。如果strip是真值,则二进制表示可能不包括有关函数的所有调试信息,以节省空间。

具有upvalues的函数只保存其upvalue数。当(重新)加载时,这些upvalues接收包含nil的新实例。(您可以使用调试库以适合您需要的方式序列化和重新加载函数的upvalues。)

string.find (s, pattern [, init [, plain]])
在字符串中查找pattern(见§6.4.1) 的第一个匹配项 s。如果找到匹配项,则find返回s 该事件开始和结束的索引 ; 否则,它返回零。第三个可选的数字参数init指定从哪里开始搜索; 它的默认值是1,可以是负数。作为第四个可选参数的值为trueplain 会关闭模式匹配工具,因此该函数执行一个简单的“查找子串”操作,没有任何字符pattern被视为魔术。注意,如果plain给出,那么也init必须给出。

如果模式具有捕获,则在成功匹配中,在两个索引之后也返回捕获的值。

string.format (formatstring, ···)
返回其可变数量的参数的格式化版本,遵循其第一个参数(必须是字符串)中给出的描述。格式字符串遵循与ISO C函数相同的规则sprintf。唯一的区别是选项/修饰符 *,h,L,l,n,和p不支持,并且有一个额外的选项,q。

该q选项在双引号之间格式化一个字符串,必要时使用转义序列,以确保Lua解释器可以安全地回读它。例如,电话

string.format('%q','带有“引号”的字符串和\ n新行')
可能会产生字符串:

“带引号的字符串\”和\
新队”
选项 A,a,E,e,f, G,和g所有期望一个数字作为论据。选项c,d, i,o,u,X,并x 期待一个整数。当使用C89编译器编译Lua时,选项A和a(十六进制浮点数)不支持任何修饰符(标志,宽度,长度)。

Option s需要一个字符串; 如果它的参数不是一个字符串,它将按照相同的规则转换为一个tostring。如果该选项具有任何修饰符(标志,宽度,长度),则字符串参数不应包含嵌入的零。

string.gmatch (s, pattern)
返回一个迭代器函数,每次调用它时,都会返回字符串中的下一个捕获pattern(参见§6.4.1)s。如果pattern指定没有捕获,则在每次调用中生成整个匹配。
例如,以下循环将遍历字符串中的所有单词s,每行打印一个:

s =“来自Lua的你好世界”
对于string.gmatch(s,“%a +”)中的w
打印(W)
结束
下一个示例key=value将给定字符串中的所有对收集到表中:

t = {}
s =“from = world,to = Lua”
for k,v in string.gmatch(s,“(%w +)=(%w +)”)do
t [k] = v
结束
对于此函数,^模式开头的插入符号不能用作锚点,因为这会阻止迭代。

string.gsub (s, pattern, repl [, n])
返回一个副本,s 其中(参见§6.4.1)的所有(或第一个n,如果给定的)出现已被替换为由其指定的替换字符串,可以是字符串,表或函数。 还返回第二个值,即发生的匹配总数。该名称来自Global SUBstitution。 patternreplgsubgsub
如果repl是字符串,则其值用于替换。字符 %可以作为转义字符:任何序列中repl的形式的,具有d 1和9之间,代表着的值d个捕获的子字符串。序列代表整场比赛。序列代表单一 。 %d%0%%%

如果repl是表,则使用第一个捕获作为键来查询每个匹配的表。

如果repl是函数,则每次匹配发生时都会调用此函数,并按顺序将所有捕获的子字符串作为参数传递。

在任何情况下,如果模式指定没有捕获,那么它的行为就像整个模式在捕获中一样。

如果表查询或函数调用返回的值是字符串或数字,则将其用作替换字符串; 否则,如果它是假或零,则没有替换(即原始匹配保留在字符串中)。

这里有些例子:

x = string.gsub(“hello world”,“(%w +)”,“%1%1”)
- > x =“hello hello world world”

x = string.gsub(“hello world”,“%w +”,“%0%0”,1)
- > x =“hello hello world”

x = string.gsub(“来自Lua的hello world”,“(%w +)%s *(%w +)”,“%2%1”)
- > x =“世界你好Lua from”

x = string.gsub(“home = $ HOME,user = $ USER”,“%$(%w +)”,os.getenv)
- > x =“home = / home / roberto,user = roberto”

x = string.gsub(“4 + 5 = $ return 4 + 5 $”,“%$(.-)%$”,函数
返回负载()
结束)
- > x =“4 + 5 = 9”

local t = {name =“lua”,version =“5.3”}
x = string.gsub(“$ name- $ version.tar.gz”,“%$(%w +)”,t)
- > x =“lua-5.3.tar.gz”
string.len (s)
接收一个字符串并返回其长度。空字符串的""长度为0.嵌入的零计数,因此"a\000bc\000"长度为5。
string.lower (s)
接收一个字符串并返回此字符串的副本,所有大写字母都更改为小写。所有其他字符保持不变。大写字母的定义取决于当前的语言环境。
string.match (s, pattern [, init])
在字符串中查找(见§6.4.1) 的第一个匹配项 。如果找到一个,则返回模式中的捕获; 否则它返回零。如果指定no capture,则返回整个匹配。第三个可选的数字参数指定从哪里开始搜索; 它的默认值是1,可以是负数。 patternsmatchpatterninit
string.pack (fmt, v1, v2, ···)
返回一个二进制字符串,其中包含根据格式字符串打包的值v1(v2等,以二进制形式序列化)fmt(参见§6.4.2)。

string.packsize (fmt)
返回由string.pack 给定格式生成的字符串的大小。格式字符串不能包含可变长度选项' s'或' z'(参见§6.4.2)。

string.rep (s, n [, sep])
返回一个字符串,该字符串是n由字符串s分隔的字符串副本的串联sep。默认值为sep空字符串(即没有分隔符)。如果n不是正数,则返回空字符串。
(请注意,只需调用此功能,即可轻松耗尽机器的内存。)

string.reverse (s)
返回一个s反转字符串的字符串。
string.sub (s, i [, j])
返回从中s开始的子字符串i 并继续直到j; i并且j可以是否定的。如果j不存在,则假定它等于-1(与字符串长度相同)。特别是,调用string.sub(s,1,j)返回s 带有length 的前缀j,string.sub(s, -i)(对于正数i)返回s 带有length 的后缀i。
如果在负指数的转换之后 i小于1,则将其校正为1.如果j大于字符串长度,则将其校正为该长度。如果在这些更正之后 i大于j,则该函数返回空字符串。

string.unpack (fmt, s [, pos])
根据格式字符串 返回打包在字符串中的值s(请参阅参考资料)(参见§6.4.2)。可选标记从哪里开始读入(默认为1)。在读取值之后,此函数还返回第一个未读字节的索引。 string.packfmtposss

string.upper (s)
接收一个字符串并返回此字符串的副本,并将所有小写字母更改为大写。所有其他字符保持不变。小写字母的定义取决于当前的语言环境。
6.4.1 - 模式
在Lua图案通过定期串,其通过模式匹配功能解释为图案描述 string.find, string.gmatch, string.gsub,和string.match。本节介绍这些字符串的语法和含义(即它们匹配的内容)。

角色类:
甲字符类用于表示一组字符。在描述字符类时允许以下组合:

x :( 其中 x不是魔术字符之一 ^$()%.[]*+-?)代表字符 x本身。
.:(一个点)代表所有字符。
%a:代表所有字母。
%c:表示所有控制字符。
%d:代表所有数字。
%g:表示除空格外的所有可打印字符。
%l:表示所有小写字母。
%p:表示所有标点字符。
%s:表示所有空格字符。
%u:表示全部大写字母。
%w:代表所有字母数字字符。
%x:表示所有十六进制数字。
%x:(其中x是任何非字母数字字符)表示字符x。这是逃避魔法角色的标准方法。任何非字母数字字符(包括所有标点字符,甚至是非魔法字符)都可以在%用于在模式中表示自身时加上' '。
[set]: 表示集合中所有字符的并集的类。可以通过使用' -' 以升序分隔范围的结束字符来指定一系列字符。上述所有类%x也可以用作集合中的组件。集合中的所有其他字符代表自己。例如,[%w_](或[_%w])表示所有字母数字字符加下划线, [0-7]表示八进制数字,并[0-7%l%-]表示八进制数字加上小写字母加上' -'字符。
您可以将一个右方括号放在一个集合中,方法是将其作为集合中的第一个字符。您可以通过将连字符定位为集合中的第一个或最后一个字符来将连字符放入集合中。(对于这两种情况,您也可以使用转义。)

范围和类之间的交互未定义。因此,模式喜欢[%a-z]或[a-%%] 没有意义。

[^set]: 表示set的补码,其中set如上所述。
对于由单个字母(%a,%c等)表示的所有类,相应的大写字母表示类的补充。例如,%S表示所有非空格字符。

字母,空格和其他字符组的定义取决于当前区域设置。特别是,该课程[a-z]可能不等同于%l。

图案项目:
甲图案项可以是

单个字符类,匹配类中的任何单个字符;
单个字符类后跟' *',它匹配类中零个或多个字符的重复。这些重复项总是匹配最长的序列;
单个字符类后跟' +',它匹配类中一个或多个重复的字符。这些重复项总是匹配最长的序列;
单个字符类后跟' -',它也匹配类中零个或多个字符的重复。与' *' 不同,这些重复项总是匹配最短的序列;
单个字符类后跟' ?',它匹配类中零个或一个字符。如果可能,它总是匹配一次;
%n,n为1到9之间; 这样的项匹配一个等于第n个捕获字符串的子字符串(见下文);
%bxy,其中x和y是两个不同的字符; 这样的项目相匹配,与开头的字符串 X,结尾 ÿ,并且其中X和Ÿ是平衡的。这意味着,如果一个读取由左到右,数串+1为X和-1的Ÿ,结束ÿ是第一Ÿ当计数到达0举例来说,该项目%b()匹配与平衡的括号表达式。
%f[set],一种前沿模式 ; 这样的项匹配任何位置的空字符串,使得下一个字符属于set ,而前一个字符不属于set。集合集如前所述进行解释。主题的开头和结尾都被处理为好像是' \0'。
图案:
甲图案是图案项的序列。^模式开头的插入符号在主题字符串的开头处锚定匹配。$模式末尾的' '将主题字符串末尾的匹配锚定在一起。在其他位置,' ^'和' $'没有特殊含义并代表自己。

捕获:
模式可以包含括在括号中的子模式; 他们描述了捕获。当匹配成功时,存储(捕获)与捕获匹配的主题字符串的子串以供将来使用。捕获根据其左括号进行编号。例如,在模式中"(a*(.)%w(%s*))",字符串匹配的一部分"a*(.)%w(%s*)"被存储为第一次捕获(因此具有数字1); 字符匹配“ .”用数字2捕获,匹配“ %s*” 的部分用数字3表示。

作为特殊情况,空捕获()捕获当前字符串位置(数字)。例如,如果我们"()aa()"在字符串上应用模式"flaaap",则会有两个捕获:3和5。

6.4.2 - 打包和解包的格式字符串
的第一个参数string.pack, string.packsize以及string.unpack 是一个格式字符串,它描述了结构的布局正在创建或读取。

格式字符串是一系列转换选项。转换选项如下:

<:设置小端
>:设大端
=:设置本机端
![n]:将最大对齐设置为n (默认为本机对齐)
b:有符号的字节(char)
B:无符号字节(char)
h:签名short(原生大小)
H:未签名short(原生大小)
l:签名long(原生大小)
L:未签名long(原生大小)
j: alua_Integer
J: alua_Unsigned
T: a size_t(原生大小)
i[n]:int带n字节的签名(默认为本机大小)
I[n]:int带n字节的无符号(默认为本机大小)
f: a float(原生大小)
d: a double(原生大小)
n: alua_Number
cn:具有n字节的固定大小的字符串
z:一个以零结尾的字符串
s[n]:一个字符串,其长度编码为带n字节的无符号整数(默认为a size_t)
x:填充的一个字节
Xop:根据选项对齐的空项op (否则将被忽略)
' ':(空格)被忽略了
(“ ”表示可选的整数。)除了填充,空格和配置(选项“ ”),每个选项对应一个参数(in )或一个结果(in )。 [n]xX <=>!string.packstring.unpack

对于选项“ ”,“ ”,“ ”和“ ”, 可以是1到16之间的任何整数。所有积分选项检查溢出; 检查给定值是否适合给定的大小; 检查读取值是否适合Lua整数。 !nsninInnstring.packstring.unpack

任何格式字符串都以“ !1=” 为前缀,即最大对齐为1(无对齐)和本机字节序开始。

对齐的工作原理如下:对于每个选项,格式获得额外的填充,直到数据以偏移量开始,该偏移量是选项大小和最大对齐之间的最小值的倍数; 此最小值必须是2的幂。选项“ c”和“ z”不对齐; 选项“ s”跟随其起始整数的对齐。

所有填充都用零填充string.pack (并忽略string.unpack)。

6.5 - UTF-8支持
该库为UTF-8编码提供基本支持。它在表格中提供了所有功能utf8。除了处理编码之外,该库不提供对Unicode的任何支持。任何需要字符含义的操作(如字符分类)都在其范围之外。

除非另有说明,否则所有期望字节位置作为参数的函数都假定给定位置是字节序列的开头或者加上主题字符串的长度。与字符串库中一样,负索引从字符串的末尾开始计算。

utf8.char (···)
接收零个或多个整数,将每个整数转换为其对应的UTF-8字节序列,并返回一个字符串,其中包含所有这些序列的串联。
utf8.charpattern
假设主题是有效的UTF-8字符串 ,模式(字符串,而不是函数)“ [\0-\x7F\xC2-\xF4][\x80-\xBF]*”(参见§6.4.1),它恰好匹配一个UTF-8字节序列。
utf8.codes (s)
返回值以便构造

for p,c in utf8.codes(s)做body end
将迭代字符串中的所有字符s,其中p包括c每个字符的位置(以字节为单位)和代码点。如果它遇到任何无效的字节序列,则会引发错误。

utf8.codepoint (s [, i [, j]])
从s 字节位置i和j(包括两者)之间的所有字符返回代码点(作为整数)。默认i值为1,而jis为i。如果它遇到任何无效的字节序列,则会引发错误。
utf8.len (s [, i [, j]])
返回字符串中s 以位置i和j(包括两者)之间开始的UTF-8字符数。默认i值为1,for j为-1。如果找到任何无效的字节序列,则返回false值加上第一个无效字节的位置。
utf8.offset (s, n [, i])
返回 从(从位置开始计数)的n第 - 字符编码开始的位置(以字节为单位) 。负数在位置之前获取字符。当为非负数时,默认值为1 ,否则,从字符串末尾获取第-th个字符的偏移量 。如果指定的字符既不在主题中也不在其结尾之后,则该函数返回nilsiniin#s + 1utf8.offset(s, -n)n。
作为一种特殊情况,当n为0时,该函数返回包含i-th字节的字符编码的开始s。

此函数假定这s是一个有效的UTF-8字符串。

6.6 - 表操作
该库提供了表操作的通用函数。它在表格中提供了所有功能table。

请记住,只要操作需要表的长度,关于长度运算符的所有警告都适用(参见§3.4.7)。所有函数都忽略作为参数给出的表中的非数字键。

table.concat (list [, sep [, i [, j]]])
给定一个列表,其中所有元素都是字符串或数字,返回字符串list[i]..sep..list[i+1] ··· sep..list[j]。默认值为sep空字符串,默认i值为1,默认j值为is #list。如果i大于j,则返回空字符串。

table.insert (list, [pos,] value)
插入元件value在位置pos中list,上移的元素 list[pos], list[pos+1], ···, list[#list]。posis 的默认值#list+1,以便在列表末尾table.insert(t,x)插入一个调用。 xt

table.move (a1, f, e, t [,a2])
将元素从表移动a1到表a2,执行等效于以下多个赋值: a2[t],··· = a1[f],···,a1[e]。默认a2是a1。目标范围可以与源范围重叠。要移动的元素数必须符合Lua整数。

返回目标表a2。

table.pack (···)
返回一个新表,其中所有参数都存储在键1,2等中,并带有n带参数总数的字段“ ”。请注意,结果表可能不是序列。

table.remove (list [, pos])
从list位置处的元素中删除pos,返回已删除元素的值。当pos是1和1之间的整数时#list,它会向下移动元素 list[pos+1], list[pos+2], ···, list[#list] 并擦除元素list[#list]; pos当#list为0时,索引也可以为0,或#list + 1; 在这些情况下,该功能会删除该元素list[pos]。

posis 的默认值#list,以便调用table.remove(l)删除列表的最后一个元素l。

table.sort (list [, comp])
排序列出一个给定的顺序元素,就地,从list[1]到list[#list]。如果comp给定,那么它必须是一个接收两个列表元素的函数,并且当第一个元素必须在最后一个顺序中的第二个元素之前时返回true(这样,在排序之后, i < j暗示not comp(list[j],list[i]))。如果comp没有给出,则使用标准Lua运算符<。

请注意,该comp函数必须对列表中的元素定义严格的部分顺序; 也就是说,它必须是不对称和传递的。否则,可能无法进行有效排序。

排序算法不稳定:按给定顺序认为相等的元素可能会通过排序改变其相对位置。

table.unpack (list [, i [, j]])
返回给定列表中的元素。这个功能相当于

返回列表[i],列表[i + 1],...,列表[j]
默认情况下,i是1并且j是#list。

6.7 - 数学函数
该库提供基本的数学函数。它在表中提供了它的所有功能和常量math。带有注释“ integer/float”的函数给出整数参数的整数结果和浮点(或混合)参数的浮点结果。舍入函数(math.ceil,math.floor和math.modf)在结果适合整数范围时返回整数,否则返回浮点数。

math.abs (x)
返回绝对值x。(整数/浮点)

math.acos (x)
返回x(以弧度表示)的反余弦值。

math.asin (x)
返回x(以弧度表示)的反正弦值。

math.atan (y [, x])
返回y/x(以弧度表示)的反正切,但使用两个参数的符号来查找结果的象限。(它也正确处理x零的情况。)

默认值为x1,以便调用math.atan(y) 返回反正切y。

math.ceil (x)
返回大于或等于的最小整数值x。

math.cos (x)
返回余弦x(假设为弧度)。

math.deg (x)
将角度x从弧度转换为度数。

math.exp (x)
返回值e x (其中e是自然对数的基数)。

math.floor (x)
返回小于或等于的最大整数值x。

math.fmod (x, y)
返回的除法的余数x由y 该舍入到零商。(整数/浮点)

math.huge
浮点值HUGE_VAL,一个大于任何其他数值的值。

math.log (x [, base])
返回x给定基数的对数。默认base值为e (以便函数返回自然对数x)。

math.max (x, ···)
根据Lua运算符返回具有最大值的参数<。(整数/浮点)

math.maxinteger
一个整数,具有整数的最大值。
math.min (x, ···)
根据Lua运算符返回具有最小值的参数<。(整数/浮点)

math.mininteger
具有整数最小值的整数。
math.modf (x)
返回的整数部分x和小数部分x。它的第二个结果总是浮动。

math.pi
π 的值。

math.rad (x)
将角度x从度数转换为弧度。

math.random ([m [, n]])
当不带参数调用时,返回一个在[0,1)范围内具有均匀分布的伪随机浮点数 。当与两个整数称为m和n, math.random返回与在范围内均匀分布的伪随机整数[M,N] 。(值nm不能为负数,必须符合Lua整数。)调用math.random(n)等效于math.random(1,n)。

此函数是C提供的underling伪随机生成器函数的接口。

math.randomseed (x)
设置x为伪随机生成器的“种子”:相等的种子生成相等的数字序列。

math.sin (x)
返回x(假设为弧度)的正弦值。

math.sqrt (x)
返回的平方根x。(您也可以使用表达式x^0.5计算此值。)

math.tan (x)
返回x(假设为弧度)的正切值。

math.tointeger (x)
如果值x可转换为整数,则返回该整数。否则,返回nil。

math.type (x)
返回“ integer”if x是整数,“ float”如果是浮点数,则返回nil,如果x不是数字则返回nil。

math.ult (m, n)
返回一个布尔值,当且仅当整数m低于整数n时,才将它们作为无符号整数进行比较。

6.8 - 输入和输出设施
I / O库为文件操作提供了两种不同的样式。第一个使用隐式文件句柄; 也就是说,有设置默认输入文件和默认输出文件的操作,所有输入/输出操作都在这些默认文件上。第二种样式使用显式文件句柄。

使用隐式文件句柄时,所有操作都由表提供io。使用显式文件句柄时,操作io.open返回文件句柄,然后所有操作都作为文件句柄的方法提供。

该表io还提供了由C它们的通常含义三个预定义的文件句柄: io.stdin,io.stdout,和io.stderr。I / O库永远不会关闭这些文件。

除非另有说明,否则所有I / O函数在失败时返回nil(加上作为第二个结果的错误消息和作为第三个结果的系统相关错误代码),并且成功时某些值与nil不同。在非POSIX系统中,错误消息和错误代码的计算可能不是线程安全的,因为它们依赖于全局C变量errno。

io.close ([file])
相当于file:close()。如果没有file,则关闭默认输出文件。

io.flush ()
相当于io.output():flush()。

io.input ([file])
使用文件名调用时,它会打开命名文件(在文本模式下),并将其句柄设置为默认输入文件。使用文件句柄调用时,它只是将此文件句柄设置为默认输入文件。当不带参数调用时,它返回当前的默认输入文件。

如果出现错误,此函数会引发错误,而不是返回错误代码。

io.lines ([filename, ···])
在读取模式下打开给定的文件名,并返回一个file:lines(···)与打开的文件类似的迭代器函数。当迭代器函数检测到文件结束时,它不返回任何值(完成循环)并自动关闭文件。

调用io.lines()(没有文件名)相当于io.input():lines("*l"); 也就是说,它遍历默认输入文件的行。在这种情况下,迭代器在循环结束时不会关闭文件。

如果出现错误,此函数会引发错误,而不是返回错误代码。

io.open (filename [, mode])
此函数以字符串中指定的模式打开文件mode。如果成功,它将返回一个新的文件句柄。

该mode字符串可以是下列任何一项:

“ r”:读取模式(默认值);
“ w”:写模式;
“ a”:追加模式;
“ r+”:更新模式,保留所有以前的数据;
“ w+”:更新模式,删除所有以前的数据;
“ a+”:追加更新模式,保留以前的数据,只允许在文件末尾写入。
该mode字符串也可以有一个“ b”末,这是需要在某些系统中以二进制方式打开该文件。

io.output ([file])
与此类似io.input,但在默认输出文件上运行。

io.popen (prog [, mode])
此功能取决于系统,并非在所有平台上都可用。

prog在一个单独的进程中 启动程序并返回一个文件句柄,您可以使用该句柄从该程序读取数据(如果mode是"r",默认)或将数据写入该程序(如果mode是"w")。

io.read (···)
相当于io.input():read(···)。

io.tmpfile ()
如果成功,则返回临时文件的句柄。此文件在更新模式下打开,并在程序结束时自动删除。

io.type (obj)
检查是否obj是有效的文件句柄。"file"如果obj是打开的文件句柄,"closed file"则返回字符串,如果obj是关闭的文件句柄,则返回nil,如果obj不是文件句柄, 则返回nil。

io.write (···)
相当于io.output():write(···)。

file:close ()
关闭file。请注意,文件在其句柄被垃圾回收时会自动关闭,但这会花费不可预测的时间。

关闭创建的文件句柄时io.popen, file:close返回返回的相同值os.execute。

file:flush ()
保存所有书面数据file。

file:lines (···)
返回一个迭代器函数,每次调用它时,都会根据给定的格式读取文件。如果没有给出格式,则使用“ l”作为默认值。作为一个例子,建设

for c in file:lines(1)do body end
将从当前位置开始迭代文件的所有字符。与io.lines此不同,此函数在循环结束时不会关闭文件。

如果出现错误,此函数会引发错误,而不是返回错误代码。

file:read (···)
file根据给定格式 读取文件,指定要读取的内容。对于每种格式,函数返回一个字符串或带有读取字符的数字,如果无法读取具有指定格式的数据,则返回nil。(在后一种情况下,该函数不读取后续格式。)在没有格式的情况下调用时,它使用读取下一行的默认格式(见下文)。

可用的格式是

“ n”: 按照Lua的词汇惯例读取数字并将其作为浮点数或整数返回。(数字可以有前导空格和符号。)此格式始终读取最长输入序列,该序列是数字的有效前缀; 如果该前缀不形成有效数字(例如,空字符串,“ 0x”或“ 3.4e-”),则将其丢弃并且函数返回nil。
“ a”: 从当前位置开始读取整个文件。在文件末尾,它返回空字符串。
“ l”: 读取跳过行尾的下一行,在文件末尾返回nil。这是默认格式。
“ L”: 读取保留行尾字符(如果存在)的下一行,在文件末尾返回nil。
number: 读取最多为此字节数的字符串,在文件末尾返回 nil。如果number为零,则它不读取任何内容并返回空字符串,或者在文件末尾返回 nil。
格式“ l”和“ L”仅应用于文本文件。

file:seek ([whence [, offset]])
设置并获取从文件开头开始测量的文件位置,offset加上由字符串指定的基数加上的位置whence,如下所示:

“ set”: base是位置0(文件的开头);
“ cur”:基数是当前位置;
“ end”: base是文件的结尾;
如果成功,则seek返回最终文件位置,以文件开头的字节为单位。如果seek失败,则返回nil,加上描述错误的字符串。

whenceis 的默认值"cur",并且for offset为0.因此,调用file:seek()返回当前文件位置,而不更改它; 调用file:seek("set")将位置设置为文件的开头(并返回0); 并且调用file:seek("end")将位置设置为文件的末尾,并返回其大小。

file:setvbuf (mode [, size])
设置输出文件的缓冲模式。有三种可用模式:

“ no”: 没有缓冲; 任何输出操作的结果立即出现。
“ full”: 完全缓冲; 仅当缓冲区已满或明确flush显示文件时才执行输出操作(请参阅参考资料io.flush)。
“ line”: 行缓冲; 输出被缓冲,直到输出换行或某些特殊文件(例如终端设备)有任何输入。
对于最后两种情况,size 指定缓冲区的大小(以字节为单位)。默认值是合适的大小。

file:write (···)
将每个参数的值写入file。参数必须是字符串或数字。

如果成功,此函数返回file。否则返回nil加上描述错误的字符串。

6.9 - 操作系统设施
该库通过表实现os。

os.clock ()
返回程序使用的CPU时间(以秒为单位)的近似值。

os.date ([format [, time]])
返回包含日期和时间的字符串或表,根据给定的字符串进行格式化format。

如果time参数存在,则表示要格式化的时间(os.time有关此值的说明,请参阅函数)。否则,date格式化当前时间。

如果format以' !' 开头,则日期格式为协调世界时。在这个可选字符之后,if format是字符串“ *t”,然后date返回一个包含以下字段的表: year,month(1-12),day(1-31), hour(0-23),min(0-59),sec(0-61 ), wday(工作日,1-7,星期日是1), yday(一年中的一天,1-366),和isdst(夏令时标志,布尔值)。如果信息不可用,则可能不存在该最后一个字段。

如果format不是“ *t”,则将date日期作为字符串返回,根据与ISO C函数相同的规则进行格式化strftime。

在不带参数的情况下调用时, date返回依赖于主机系统和当前语言环境的合理日期和时间表示。(更具体地说,os.date()相当于os.date("%c")。)

在非POSIX系统中,由于它依赖于C函数gmtime和C函数,因此该函数可能不是线程安全的localtime。

os.difftime (t2, t1)
返回t1不时t2 (以秒为单位)的差异(其中时间是返回的值os.time)。在POSIX,Windows和其他一些系统中,这个值恰好是t2-t1。

os.execute ([command])
此功能相当于ISO C功能system。它传递command给操作系统shell执行。 如果命令成功终止,则第一个结果为true,否则为nil。在第一个结果之后,函数返回一个字符串加一个数字,如下所示:

“ exit”: 命令正常终止; 以下数字是命令的退出状态。
“ signal”: 命令被一个信号终止; 以下数字是终止命令的信号。
在没有a的情况下调用时command, os.execute如果shell可用,则返回一个true的布尔值。

os.exit ([code [, close]])
调用ISO C函数exit来终止宿主程序。如果code为true,则返回状态为EXIT_SUCCESS; 如果code为false,则返回状态为EXIT_FAILURE; 如果code是数字,则返回的状态为此数字。作为默认值code是真。

如果可选的第二个参数close为true,则在退出之前关闭Lua状态。

os.getenv (varname)
返回流程环境变量的值,如果未定义变量varname,则返回nil。

os.remove (filename)
使用给定名称删除文件(或POSIX系统上的空目录)。如果此函数失败,则返回nil,加上描述错误和错误代码的字符串。否则,它返回true。

os.rename (oldname, newname)
重命名指定的文件或目录oldname来newname。如果此函数失败,则返回nil,加上描述错误和错误代码的字符串。否则,它返回true。

os.setlocale (locale [, category])
设置程序的当前区域设置。 locale是一个依赖于系统的字符串,用于指定语言环境; category是可选的字符串描述改变哪一类: "all","collate","ctype", "monetary","numeric",或"time"; 默认类别是"all"。该函数返回新语言环境的名称,如果无法满足请求,则返回nil。

如果locale是空字符串,则将当前语言环境设置为实现定义的本机语言环境。如果locale是字符串“ C”,则将当前语言环境设置为标准C语言环境。

当使用nil作为第一个参数调用时,此函数仅返回给定类别的当前语言环境的名称。

由于它依赖于C函数,该函数可能不是线程安全的setlocale。

os.time ([table])
返回不带参数调用的当前时间,或表示给定表指定的本地日期和时间的时间。此表必须包含字段year,, month和day,并且可能包含字段 hour(默认值为12), min(默认值为0), sec(默认值为0)和isdst(默认值为nil)。其他字段将被忽略。有关这些字段的说明,请参阅该os.date函数。

这些字段中的值不需要在其有效范围内。例如,如果sec是-10,则表示从其他字段指定的时间起-10秒; 如果hour是1000,则表示从其他字段指定的时间开始+1000小时。

返回的值是一个数字,其含义取决于您的系统。在POSIX,Windows和其他一些系统中,此数字计算自某个给定开始时间(“epoch”)以来的秒数。在其它系统中,意思是未指定,并且通过返回的数字time只能用于作为参数 os.date和os.difftime。

os.tmpname ()
返回一个文件名,该文件名可用于临时文件。该文件必须在使用前显式打开,并在不再需要时显式删除。

在POSIX系统中,此功能还会创建具有该名称的文件,以避免安全风险。(在获取名称和创建文件之间的时间内,其他人可能会创建具有错误权限的文件。)您仍然必须打开文件才能使用它并将其删除(即使您不使用它)。

如果可能,您可能更喜欢使用io.tmpfile,它会在程序结束时自动删除文件。

6.10 - 调试库
该库为Lua程序提供调试接口(第4.9节)的功能。使用此库时应小心谨慎。它的一些功能违反了关于Lua代码的基本假设(例如,函数本地的变量不能从外部访问; Lua代码不能更改用户数据元表; Lua程序不会崩溃),因此可能危及其他安全代码。此外,此库中的某些功能可能很慢。

该库中提供了此库中的所有函数debug。所有在线程上运行的函数都有一个可选的第一个参数,它是要操作的线程。默认值始终是当前线程。

debug.debug ()
与用户一起进入交互模式,运行用户输入的每个字符串。使用简单的命令和其他调试工具,用户可以检查全局和局部变量,更改其值,计算表达式等。仅包含单词的行cont结束此功能,以便调用者继续执行。

请注意,命令debug.debug不会在词法上嵌套在任何函数中,因此无法直接访问局部变量。

debug.gethook ([thread])
返回线程的当前挂钩设置,作为三个值:当前挂钩函数,当前挂钩掩码和当前挂钩计数(由debug.sethook函数设置)。

debug.getinfo ([thread,] f [, what])
返回包含函数信息的表。你可以直接给出函数,或者你可以给一个数字作为值f,这意味着f在给定线程的调用堆栈级别运行的函数:level 0是当前函数(getinfo本身); 级别1是调用的函数getinfo (尾部调用除外,它不依赖于堆栈); 等等。如果f数字大于活动函数的数量,则getinfo返回nil。

返回的表可以包含返回的所有字段lua_getinfo,字符串what描述要填写的字段。默认设置what是获取所有可用信息,但有效行表除外。如果存在,则选项' f'添加以func函数本身命名的字段。如果存在,则选项' L'添加一个以activelines有效行表命名的字段。

例如debug.getinfo(1,"n").name,如果可以找到合理的名称,则表达式返回当前函数的名称,表达式debug.getinfo(print) 返回一个表,其中包含有关该print函数的所有可用信息。

debug.getlocal ([thread,] f, local)
此函数返回局部变量的名称和值local,其中函数的索引f位于堆栈级别。此函数不仅访问显式局部变量,还访问参数,临时变量等。

第一个参数或局部变量具有索引1,依此类推,遵循它们在代码中声明的顺序,仅计算当前函数范围内活动的变量。负指数是指vararg论证; -1是第一个vararg参数。如果没有给定索引的变量,则函数返回nil,并在调用超出范围的级别时引发错误。(您可以调用debug.getinfo以检查级别是否有效。)

以' ('(左括号)开头的变量名称表示没有已知名称的变量(内部变量,如循环控制变量,以及保存没有调试信息的块中的变量)。

该参数f也可以是函数。在这种情况下,getlocal只返回函数参数的名称。

debug.getmetatable (value)
如果没有 metatable,则返回给定value 或nil的metatable。

debug.getregistry ()
返回注册表(参见§4.5)。

debug.getupvalue (f, up)
此函数返回upvalue的名称和值以及up函数的索引f。该函数返回nil如果给定索引没有upvalue,则。

以' ('(左括号)开头的变量名称表示没有已知名称的变量(来自没有调试信息的块保存的变量)。

debug.getuservalue (u)
返回与之关联的Lua值u。如果u不是完整的用户数据,则返回nil。

debug.sethook ([thread,] hook, mask [, count])
将给定函数设置为钩子。字符串mask和数字count描述何时调用挂钩。字符串掩码可以具有以下字符的任意组合,具有给定含义:

' c':每次Lua调用一个函数时都会调用该钩子;
' r':每次Lua从函数返回时调用钩子;
' l':每次Lua进入新的代码行时都会调用该钩子。
此外,与count零不同,在每个count指令之后也会调用钩子。

当没有参数调用时, debug.sethook关闭钩子。

当钩被调用时,它的第一个参数是描述已经触发了呼叫事件的字符串: "call"(或"tail call") "return", "line"和"count"。对于行事件,钩子还将新行号作为其第二个参数。在钩子内部,您可以getinfo使用级别2 调用以获取有关正在运行的函数的更多信息(级别0是getinfo函数,级别1是钩子函数)。

debug.setlocal ([thread,] level, local, value)
此函数将值赋给value局部变量,并在堆栈local级别使用函数的索引level。如果没有给定索引的局部变量,则函数返回nil,并在level超出范围调用时引发错误。(您可以调用getinfo以检查级别是否有效。)否则,它返回局部变量的名称。

debug.getlocal有关变量索引和名称的更多信息, 请参阅。

debug.setmetatable (value, table)
将给定的metatable设置为给value定table (可以为nil)。退货value。

debug.setupvalue (f, up, value)
此函数分配值value与索引的upvalue up的功能f。如果给定索引没有upvalue,则函数返回nil。否则,它返回upvalue的名称。

debug.setuservalue (udata, value)
将给定value值设置为与给定关联的Lua值udata。 udata必须是完整的用户数据。

退货udata。

debug.traceback ([thread,] [message [, level]])
如果message存在但既不是字符串也不是nil,则此函数返回message而不进行进一步处理。否则,它返回一个字符串,其中包含调用堆栈的回溯。可选message字符串附加在回溯的开头。可选level数字指示启动回溯的级别(默认值为1,函数调用traceback)。

debug.upvalueid (f, n)
返回n 从给定函数编号的upvalue的唯一标识符(作为light userdata)。

这些唯一标识符允许程序检查不同的闭包是否共享up值。共享upvalue的Lua闭包(即访问相同的外部局部变量)将为这些upvalue索引返回相同的id。

debug.upvaluejoin (f1, n1, f2, n2)
使n1Lua闭包f1 的n2-th upvalue 引用Lua闭包的-th upvalue f2。

7 - Lua Standalone
尽管Lua被设计为扩展语言,但要嵌入到主机C程序中,它也经常被用作独立语言。Lua作为一种独立语言的解释器,简单地称为lua标准分发。独立解释器包括所有标准库,包括调试库。它的用法是:

lua [options] [script [args]]
选项是:

-e stat:执行字符串统计 ;
-l mod: “requires” mod并将结果赋给global @ mod ;
-i:运行脚本后进入交互模式;
-v:打印版本信息;
-E:忽略环境变量;
--:停止处理选项;
-:stdin作为文件执行并停止处理选项。
处理lua完选项后,运行给定的脚本。在不带参数的情况下调用时, lua其行为lua -v -i 与标准输入(stdin)是终端时的行为相同lua -。

在没有选项-E的情况下调用时,解释器在运行任何参数之前检查环境变量LUA_INIT_5_3 (或者LUA_INIT如果未定义版本化名称)。如果变量内容具有格式,则执行该文件。否则,执行字符串本身。 @filenamelualua

当使用选项调用时-E,除了忽略之外LUA_INIT,Lua还会忽略和的值,LUA_PATH并LUA_CPATH设置package.path和中package.cpath 定义的默认路径的值 luaconf.h。

除了-i和之外,所有选项都按顺序处理-E。例如,像一个调用

$ lua -e'a = 1'-e'print(a)'script.lua
将首先设置a为1,然后打印值a,最后运行script.lua没有参数的文件。(这$是shell提示符。您的提示可能有所不同。)

在运行任何代码之前,请 lua在名为的全局表中收集所有命令行参数arg。脚本名称转到索引0,脚本名称转到索引1后的第一个参数,依此类推。脚本名称之前的任何参数(即解释器名称及其选项)都转到负索引。例如,在通话中

$ lua -la b.lua t1 t2
表格是这样的:

arg = {[ - 2] =“lua”,[ - 1] =“ - la”,
[0] =“b.lua”,
[1] =“t1”,[2] =“t2”}
如果调用中没有脚本,则解释器名称将转到索引0,然后是其他参数。例如,电话

$ lua -e“print(arg [1])”
将打印“ -e”。如果有一个脚本,该脚本调用参数 arg[1],..., arg[#arg]。(就像Lua中的所有块一样,脚本被编译为vararg函数。)

在交互模式下,Lua反复提示并等待一条线。读完一行后,Lua首先尝试将该行解释为表达式。如果成功,则打印其值。否则,它将该行解释为语句。如果您编写了不完整的语句,则解释程序会通过发出不同的提示来等待其完成。

如果全局变量_PROMPT包含字符串,则其值将用作提示。同样,如果全局变量_PROMPT2包含字符串,则其值将用作辅助提示符(在不完整语句期间发出)。

如果脚本中存在未受保护的错误,则解释程序会将错误报告给标准错误流。如果错误对象不是字符串但具有元方法__tostring,则解释器会调用此元方法来生成最终消息。否则,解释器将错误对象转换为字符串并向其添加堆栈跟踪。

正常完成后,口译员关闭其主要的Lua状态(见lua_close)。该脚本可以通过调用os.exit终止来避免此步骤。

为了允许在Unix系统中使用Lua作为脚本解释器,独立解释器跳过块的第一行(如果它开始)#。因此,Lua脚本可以通过使用chmod +x和 #!形式制作成可执行程序,如

#!的/ usr / local / bin目录/ LUA
(当然,Lua解释器的位置可能与您的机器不同。如果在您的机器lua中PATH,那么

#!/ usr / bin / env lua
是一个更便携的解决方案。)

8 - 与先前版本不兼容
这里我们列出了将程序从Lua 5.2移动到Lua 5.3时可能会发现的不兼容性。您可以通过使用适当的选项编译Lua来避免一些不兼容性(请参阅文件luaconf.h)。但是,将来将删除所有这些兼容性选项。

Lua版本总是可以以不暗示程序中源代码更改的方式更改C API,例如常量的数值或作为宏的函数实现。因此,您不应该假设二进制文件在不同的Lua版本之间是兼容的。使用新版本时,始终重新编译Lua API的客户端。

同样,Lua版本总是可以改变预编译块的内部表示; 预编译的块在不同的Lua版本之间不兼容。

官方发布中的标准路径可能会在不同版本之间发生变化

8.1 - 语言的变化
Lua 5.2和Lua 5.3之间的主要区别在于引入了数字的整数子类型。尽管此更改不应影响“正常”计算,但某些计算(主要涉及某种溢出的计算)可能会产生不同的结果。
您可以通过强制数字为浮点数来修正这些差异(在Lua 5.2中,所有数字都是浮点数),特别是用结尾写入常量.0 或使用x = x + 0.0转换变量。(此建议仅用于快速修复偶然的不兼容性;它不是良好编程的一般准则。对于良好的编程,使用需要浮点数的浮点数和需要整数的整数。)

如果float .0看起来像一个整数,那么将float转换为字符串现在会为结果添加一个后缀。(例如,float 2.0将打印为2.0,而不是2。)当您需要特定的数字格式时,应始终使用显式格式。
(形式上这不是不兼容的,因为Lua没有指定如何将数字格式化为字符串,但某些程序采用特定格式。)

垃圾收集器的世代模式已被删除。(这是Lua 5.2中的一个实验性功能。)
8.2 - 图书馆的变化
该bit32库已被弃用。很容易需要兼容的外部库,或者更好的是,用适当的按位操作替换它的功能。(请记住,bit32对32位整数进行操作,而Lua 5.3中的按位运算符对Lua整数进行操作,默认情况下为64位。)
表库现在尊重用于设置和获取元素的元方法。
该ipairs迭代器现在尊重元方法及其__ipairs元方法已被弃用。
选项名称中io.read没有首字母' *'。为了兼容性,Lua将继续接受(并忽略)此角色。
下面的功能已废弃的数学库: atan2,cosh,sinh,tanh,pow, frexp,和ldexp。您可以替换math.pow(x,y)使用x^y; 您可以替换math.atan2使用math.atan,现在接受一个或两个参数; 你可以替换math.ldexp(x,exp)使用x * 2.0^exp。对于其他操作,您可以使用外部库或在Lua中实现它们。
使用的C加载器的搜索器require 改变了它处理版本化名称的方式。现在,版本应该在模块名称之后(在大多数其他工具中通常)。为了兼容性,如果根据新样式找不到打开的函数,那个搜索者仍会尝试旧格式。(Lua 5.2已经按照这种方式工作,但它没有记录这一变化。)
该调用collectgarbage("count")现在只返回一个结果。(您可以从第一个结果的小数部分计算第二个结果。)
8.3 - API的变化
延续函数现在作为参数接收它们需要通过的内容lua_getctx,因此lua_getctx已被删除。相应地调整您的代码。
函数lua_dump有一个额外的参数,strip。使用0作为此参数的值以获取旧行为。
功能注入/项目无符号整数(lua_pushunsigned,lua_tounsigned,lua_tounsignedx, luaL_checkunsigned,luaL_optunsigned)就被抛弃了。使用带有类型转换的签名等效项。
宏项目非默认的整数类型(luaL_checkint,luaL_optint,luaL_checklong,luaL_optlong)就被抛弃了。在lua_Integer类型转换中使用它们的等价物(或者,如果可能,lua_Integer在代码中使用)。
9 - Lua的完整语法
以下是扩展BNF中Lua的完整语法。与扩展BNF中一样,{A}表示0或更多As,而[A]表示可选A.(有关运算符优先级,请参见§3.4.8 ;有关终端Name,Numeral和LiteralString的说明,请参阅§ 3.1。)

chunk :: = block

block :: = {stat} [retstat]

stat :: =' ;'|
varlist' = 'explist |
functioncall |
标签|
休息 |
转到名称|
不要阻止结束 |
而 exp 会阻止结束 |
重复阻止直到 exp |
如果 exp 然后阻塞{ elseif exp 然后阻止} [ else block] end |
for Name' = 'exp' , 'exp [' , 'exp] do block end |
对于名称列表中 explist不要阻止结束 |
function funcname funcbody |
local 函数名称funcbody |
本地名单[' = 'explist]

retstat :: = return [explist] [' ; “]

label :: =' :: 'Name' :: '

funcname :: = Name {' 。'姓名} [' : '姓名]

varlist :: = var {' , 'var}

var :: = Name | prefixexp' [ 'exp' ] '| prefixexp' 。' 名称

namelist :: = Name {' , 'Name}

explist :: = exp {' , 'exp}

exp :: = nil | 假 | 是的 | 数字| LiteralString | ' ... '| functiondef |
prefixexp | tableconstructor | exp binop exp | unop exp

prefixexp :: = var | functioncall | ' ( 'exp' ) '

functioncall :: = prefixexp args | prefixexp' : '名称args

args :: =' ( '[explist]' ) '| tableconstructor | LiteralString

functiondef :: = function funcbody

funcbody :: =' ( '[parlist]' ) '阻止结束

parlist :: = namelist [' , '' ... '] | ' ... '

tableconstructor :: =' { '[fieldlist]' } '

fieldlist :: = field {fieldsep field} [fieldsep]

field :: =' [ 'exp' ] '' = 'exp | 名称' = 'exp | EXP

fieldsep :: =' , '| ' ; “

binop :: =' + '| ' - '| ' * '| ' / '| ' // '| ' ^ '| ' % '|
' & '| ' 〜 '| ' | '| ' >> '| ' << '| ' .. '|
' < '| ' <= '| ' > '| ' > = '| ' == '| ' 〜= '|
和 | 要么

unop :: =' - '| 不是 | ' # '| ' 〜 '

最后更新:tue jun 26 13:16:37 -03 2018

上一篇:lua 学习笔记(1)


下一篇:使用Nginx+Lua代理Hadoop HA