Nvim 的 `:help` 页面,生成 于 源 使用 tree-sitter-vimdoc 解析器。
and break do else elseif end false for function if in local nil not or repeat return then true until while
+ - * / % ^ # == ~= <= >= < > = ( ) { } [ ] ; : , . .. ...
\a
响铃\b
退格\f
换页\n
换行\r
回车\t
水平制表符\v
垂直制表符\\
反斜杠\"
引号(双引号)\'
撇号(单引号)a = 'alo\n123"'
a = "alo\n123\""
a = '\97lo\10\04923"'
a = [[alo
123"]]
a = [==[
alo
123"]==]
3 3.0 3.1416 314.16e-2 0.31416E1 0xff 0x56
var ::= Name
var ::= prefixexp [ exp ]
prefixexp
) 应该得到一个表值; 第二个表达式 (exp
) 标识该表内的一个特定条目。 用于标识要索引的表的表达式具有受限的语法; 有关详细信息,请参见 lua-expressions。var.NAME
只是 var["NAME"]
的语法糖。var ::= prefixexp . Name
getfenv
(参见 lua_getfenv())。 要替换它,请调用 setfenv
(参见 setfenv())。(您只能通过调试库(参见 lua-lib-debug)来操作 C 函数的环境)。x
的访问等同于 _env.x
,而这又等同于gettable_event(_env, "x")
_env
是运行函数的环境。(_env
变量未在 Lua 中定义。 我们在这里仅出于解释目的使用它)。t[i]
的访问等同于调用 gettable_event(t,i)
。(有关 gettable_event
函数的完整描述,请参见 lua-metatable。 此函数未在 Lua 中定义或可调用。 我们在这里仅出于解释目的使用它)。chunk ::= {stat [ ; ]}
;;
不合法。luac
。 源代码和编译后的代码形式可以互换使用;Lua 会自动检测文件类型并相应地执行。block ::= chunk
stat ::= varlist1 = explist1 varlist1 ::= var { , var } explist1 ::= exp { , exp }
nil
扩展。 如果表达式列表以函数调用结束,则该调用返回的所有值都会在调整之前进入值列表(除非调用被括号括起来;参见 lua-expressions)。i = 3
i, a[i] = i+1, 20
a[3]
设置为 20,不会影响 a[4]
,因为 a[i]
中的 i
在被赋值为 4 之前就已经被计算(为 3)。 同样,这行代码x, y = y, x
x
和 y
的值。t[i] = val
的赋值等同于 settable_event(t,i,val)
。(有关 settable_event
函数的完整描述,请参见 lua-metatable。 此函数未在 Lua 中定义或可调用。 我们在这里仅出于解释目的使用它)。x = val
的赋值等同于赋值 _env.x = val
,而这又等同于settable_event(_env, "x", val)
_env
是运行函数的环境。(_env
变量未在 Lua 中定义。 我们在这里仅出于解释目的使用它)。if
、while
和 repeat
具有通常的含义和熟悉的语法stat ::= while exp do block end stat ::= repeat block until exp stat ::= if exp then block { elseif exp then block } [ else block ] end
for
语句,它有两种形式(参见 lua-for)。false
和 nil
都被视为假。 所有与 nil
和 false
不同的值都被视为真(尤其是数字 0 和空字符串也被视为真)。repeat-until
循环中,内部代码块不以 until
关键字结尾,而是在条件之后结束。 因此,条件可以引用循环代码块内声明的局部变量。stat ::=
return
[explist1]
stat ::=
break
break
会结束最内层的循环。return
和 break
语句只能作为代码块的最后
一条语句编写。 如果必须在代码块中间return
或 break
,则可以使用显式的内部代码块,如 do return end
和 do break end
中的习惯用法,因为现在 return
和 break
是其(内部)代码块中的最后一条语句。for
语句有两种形式:一种是数值型的,另一种是泛型的。for
循环在控制变量遍历算术级数时重复一段代码。 它具有以下语法stat ::= for Name = exp , exp [ , exp ] do block end
block
从第一个 exp
的值开始重复执行,直到它以第三个 exp
为步长超过第二个 exp
。 更准确地说,类似于for var = e1, e2, e3 do block end
for
语句等同于以下代码do
local var, limit, step = tonumber(e1), tonumber(e2), tonumber(e3)
if not ( var and limit and step ) then error() end
while ( step >0 and var <= limit )
or ( step <=0 and var >= limit ) do
block
var = var + step
end
end
var
、limit
和 step
是不可见的变量。 这些名称仅用于解释目的。break
退出 for
循环。var
对循环来说是局部的;您不能在 for
结束或被中断后使用它的值。 如果需要这个值,请在中断或退出循环之前将其赋值给另一个变量。for
语句使用称为 迭代器 的函数进行操作。 在每次迭代中,都会调用迭代器函数以生成一个新值,当此新值为 nil
时停止。 泛型 for
循环具有以下语法stat ::= for namelist in explist1 do block end namelist ::= Name { , Name }
for
var1, ..., varn
in
explist
do
block
end
for
语句等同于以下代码do
local f, s, var = explist
while true do
local var1, ..., varn = f(s, var)
var = var1
if var == nil then break end
block
end
end
for
语句,explist
只计算一次。 其结果是一个迭代器函数、一个 state
和第一个迭代器变量的初始值。f
、s
和 var
是不可见的变量。 这些名称仅用于解释目的。break
退出 for
循环。var1, ..., varn
对循环来说是局部的;您不能在 for
结束之后使用它们的值。 如果需要这些值,请在中断或退出循环之前将其赋值给其他变量。stat ::= functioncall
stat ::= local namelist [ = explist1 ] namelist ::= Name { , Name }
nil
初始化。exp ::= prefixexp exp ::= nil | false | true exp ::= Number exp ::= String exp ::= function exp ::= tableconstructor exp ::= ... exp ::= exp binop exp exp ::= unop exp prefixexp ::= var | functioncall | ( exp )
...
) 表示)只能在变参函数内部使用;它们在 lua-function-define 中解释。not
(参见 lua-logicalop)和一元长度运算符(参见 lua-length)。f() -- adjusted to 0 results
g(f(), x) -- f() is adjusted to 1 result
g(x, f()) -- g gets x plus all results from f()
a,b,c = f(), x -- f() is adjusted to 1 result (c gets nil)
a,b = ... -- a gets the first vararg parameter, b gets
-- the second (both a and b may get nil if there
-- is no corresponding vararg parameter)
a,b,c = x, f() -- f() is adjusted to 2 results
a,b,c = f() -- f() is adjusted to 3 results
return f() -- returns all results from f()
return ... -- returns all received vararg parameters
return x,y,f() -- returns x, y, and all results from f()
{f()} -- creates a list with all results from f()
{...} -- creates a list with all vararg parameters
{f(), nil} -- f() is adjusted to 1 result
(f(x,y,z))
始终是一个单一值,即使 f
返回多个值。((f(x,y,z))
的值为 f
返回的第一个值,如果 f
没有返回值,则为 nil
。)+
(加法)、-
(减法)、*
(乘法)、/
(除法)、%
(取模)和 ^
(求幂);以及一元运算符 -
(取反)。如果操作数是数字,或者可以转换为数字的字符串(参见 lua-coercion),则所有运算具有通常的含义。求幂运算适用于任何指数。例如,x^(-0.5)
计算 x
的平方根的倒数。取模运算定义如下a % b == a - math.floor(a/b)*b
== ~= < > <= >=
false
或 true
。==
) 首先比较其操作数的类型。如果类型不同,则结果为 false
。否则,比较操作数的值。数字和字符串以通常的方式比较。对象(表、userdata、线程和函数)通过引用进行比较:只有当两个对象是同一个对象时,它们才被认为相等。每次创建新对象(表、userdata 或函数)时,此新对象都与任何先前存在的对象不同。~=
恰好是相等运算符 (==
) 的否定。and or not
not
始终返回 false
或 true
。合取运算符 and
返回其第一个参数,如果此值为 false
或 nil
;否则,and
返回其第二个参数。析取运算符 or
返回其第一个参数,如果此值不同于 nil
和 false
;否则,or
返回其第二个参数。and
和 or
都使用短路求值,也就是说,只有在必要时才求值第二个操作数。以下是一些示例10 or 20 --> 10 10 or error() --> 10 nil or "a" --> "a" nil and 10 --> nil false and error() --> false false and nil --> false false or nil --> nil 10 and 20 --> 20
-->
表示前面表达式的结果。)..
) 表示。如果两个操作数都是字符串或数字,则根据 lua-coercion 中提到的规则将它们转换为字符串。否则,将调用 "concat" 元方法(参见 lua-metatable)。#
表示。字符串的长度是指其字节数(即,每个字符都是一个字节时字符串长度的通常含义)。t
的长度被定义为任何整型索引 n
,使得 t[n]
不为 nil
且 t[n+1]
为 nil
;此外,如果 t[1]
为 nil
,则 n
可以为零。对于一个正规数组,其非 nil 值从 1 到给定的 n
,其长度恰好是那个 n
,即其最后一个值的索引。如果数组有 "空洞"(即,其他非 nil 值之间的 nil
值),则 #t
可以是直接位于 nil
值之前的任何索引(即,它可以将任何这样的 nil
值视为数组的结尾)。or and < > <= >= ~= == .. + - * / not # - (unary) ^
..
) 和求幂运算符 (^
) 是右结合的。所有其他二元运算符都是左结合的。tableconstructor ::= { [ fieldlist ] } fieldlist ::= field { fieldsep field } [ fieldsep ] field ::= [ exp ] = exp | Name = 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 }
do
local t = {}
t[f(1)] = g
t[1] = "x" -- 1st exp
t[2] = "y" -- 2nd exp
t.x = 1 -- temp["x"] = 1
t[3] = f(x) -- 3rd exp
t[30] = 23
t[4] = 45 -- 4th exp
a = t
end
exp
形式,并且表达式是函数调用,则该调用返回的所有值将依次进入列表(参见 lua-function)。为了避免这种情况,请将函数调用括在括号中(参见 lua-expressions)。functioncall ::= prefixexp args
prefixexp
和 args
。如果 prefixexp
的值为 function
类型,则使用给定的参数调用此函数。否则,将调用 prefixexp
的 "call" 元方法,其第一个参数为 prefixexp
的值,之后是原始调用参数(参见 lua-metatable)。functioncall ::= prefixexp : Name args
v:name(
args
)
是 v.name(v,
args
)
的语法糖,除了 v
只被评估一次。args ::= ( [ explist1 ] ) args ::= tableconstructor args ::= String
f{
fields
}
形式的调用是 f({
fields
})
的语法糖,也就是说,参数列表是一个新的单一表。f'
string
'
形式的调用(或 f"
string
"
或 f[[
string
]]
)是 f('
string
')
的语法糖,也就是说,参数列表是一个单一的字面字符串。(
之前放置换行符。此限制避免了语言中的一些歧义。如果您编写a = f
(g).x(a)
a = f(g).x(a)
。因此,如果您想要两条语句,则必须在它们之间添加一个分号。如果您实际上想要调用 f
,则必须删除 (g)
之前的换行符。return
functioncall
形式的调用称为尾调用。Lua 实现正确的尾调用(或正确的尾递归):在尾调用中,被调用函数会重用调用函数的堆栈条目。因此,程序可以执行的嵌套尾调用数量没有限制。但是,尾调用会擦除调用函数的任何调试信息。请注意,尾调用只会在特定语法下发生,其中 return
只有一个函数调用作为参数;这种语法使得调用函数准确地返回被调用函数的返回值。因此,以下示例都不是尾调用return (f(x)) -- results adjusted to 1
return 2 * f(x)
return x, f(x) -- additional results
f(x); return -- results discarded
return x or f(x) -- results adjusted to 1
function ::= function funcbody funcbody ::= ( [ parlist1 ] ) block end
stat ::= function funcname funcbody stat ::= local function Name funcbody funcname ::= Name { . Name } [ : Name ]
function f ()
body
end
f = function ()
body
end
function t.a.b.c.f ()
body
end
t.a.b.c.f = function ()
body
end
local function f ()
body
end
local f; f = function f ()
body
end
local f = function f ()
body
end
f
的引用时才会有所不同。)function
类型。当 Lua 预编译一个代码块时,其所有函数体也会被预编译。然后,每当 Lua 执行函数定义时,都会实例化(或闭包)该函数。此函数实例(或闭包)是表达式的最终值。同一函数的不同实例可能引用不同的外部局部变量,并且可能具有不同的环境表。parlist1 ::= namelist [ , ... ] | ...
...
) 表示。vararg 函数不会调整其参数列表;相反,它会收集所有额外的参数,并将它们通过 vararg 表达式传递给函数,该表达式也用三个点表示。此表达式的值为所有实际额外参数的列表,类似于具有多个结果的函数。如果在另一个表达式中或在表达式列表的中间使用 vararg 表达式,则其返回值列表将调整为一个元素。如果该表达式用作表达式列表的最后一个元素,则不会进行调整(除非调用被括在括号中)。function f(a, b) end
function g(a, b, ...) end
function r() return 1,2,3 end
CALL PARAMETERS f(3) a=3, b=nil 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, ... --> (nothing) g(3, 4) a=3, b=4, ... --> (nothing) g(3, 4, 5, 8) a=3, b=4, ... --> 5 8 g(5, r()) a=5, b=1, ... --> 2 3
function t.a.b.c:f (
params
)
body
end
t.a.b.c:f = function (
self
, params
)
body
end
x = 10 -- global variable
do -- new block
local x = x -- new `x`, with value 10
print(x) --> 10
x = x+1
do -- another block
local x = x+1 -- another `x`
print(x) --> 12
end
print(x) --> 11
end
print(x) --> 10 (the global one)
local x = x
这样的声明中,新声明的 x
尚未处于作用域中,因此第二个 x
指的是外部变量。a = {}
local x = 20
for i=1,10 do
local y = 0
a[i] = function () y=y+1; return x+y end
end
y
变量,而它们都共享同一个 x
。"__add"
字段中的函数。如果找到,Lua 会调用该函数来执行加法。getmetatable
函数(参见 getmetatable())查询任何值的元表。setmetatable
函数(参见 setmetatable())替换表格的元表。你不能从 Lua 中更改其他类型的元表(除非使用调试库);你必须为此使用 C API。__
为前缀;例如,操作 "add" 的键是字符串 "__add"。这些操作的语义最好由一个 Lua 函数来解释,该函数描述了解释器如何执行该操作。rawget
、tonumber
等)都在 lua-lib-core 中描述。特别是,要检索给定对象的元方法,我们使用表达式metatable(obj)[event]
rawget(metatable(obj) or {}, event)
nil
)。getbinhandler
函数定义了 Lua 如何为二元运算选择一个处理程序。首先,Lua 会尝试第一个操作数。如果它的类型没有为该操作定义处理程序,那么 Lua 会尝试第二个操作数。function getbinhandler (op1, op2, event)
return metatable(op1)[event] or metatable(op2)[event]
end
op1 + op2
的行为是function add_event (op1, op2)
local o1, o2 = tonumber(op1), tonumber(op2)
if o1 and o2 then -- both operands are numeric?
return o1 + o2 -- `+` here is the primitive `add`
else -- at least one of the operands is not numeric
local h = getbinhandler(op1, op2, "__add")
if h then
-- call the handler with both operands
return h(op1, op2)
else -- no handler available: default behavior
error(...)
end
end
end
-
操作。function unm_event (op)
local o = tonumber(op)
if o then -- operand is numeric?
return -o -- `-` here is the primitive `unm`
else -- the operand is not numeric.
-- Try to get a handler from the operand
local h = metatable(op).__unm
if h then
-- call the handler with the operand
return h(op)
else -- no handler available: default behavior
error(...)
end
end
end
..
(连接)操作。function concat_event (op1, op2)
if (type(op1) == "string" or type(op1) == "number") and
(type(op2) == "string" or type(op2) == "number") then
return op1 .. op2 -- primitive string concatenation
else
local h = getbinhandler(op1, op2, "__concat")
if h then
return h(op1, op2)
else
error(...)
end
end
end
#
操作。function len_event (op)
if type(op) == "string" then
return strlen(op) -- primitive string length
elseif type(op) == "table" then
return #op -- primitive table length
else
local h = metatable(op).__len
if h then
-- call the handler with the operand
return h(op)
else -- no handler available: default behavior
error(...)
end
end
end
getcomphandler
函数定义了 Lua 如何为比较运算符选择一个元方法。只有当两个要比较的对象具有相同的类型以及为所选操作相同的元方法时,才会选择一个元方法。function getcomphandler (op1, op2, event)
if type(op1) ~= type(op2) then return nil end
local mm1 = metatable(op1)[event]
local mm2 = metatable(op2)[event]
if mm1 == mm2 then return mm1 else return nil end
end
function eq_event (op1, op2)
if type(op1) ~= type(op2) then -- different types?
return false -- different objects
end
if op1 == op2 then -- primitive equal?
return true -- objects are equal
end
-- try metamethod
local h = getcomphandler(op1, op2, "__eq")
if h then
return h(op1, op2)
else
return false
end
end
a ~= b
等价于 not (a == b)
。<
操作。function lt_event (op1, op2)
if type(op1) == "number" and type(op2) == "number" then
return op1 < op2 -- numeric comparison
elseif type(op1) == "string" and type(op2) == "string" then
return op1 < op2 -- lexicographic comparison
else
local h = getcomphandler(op1, op2, "__lt")
if h then
return h(op1, op2)
else
error(...);
end
end
end
a > b
等价于 b < a
。<=
操作。function le_event (op1, op2)
if type(op1) == "number" and type(op2) == "number" then
return op1 <= op2 -- numeric comparison
elseif type(op1) == "string" and type(op2) == "string" then
return op1 <= op2 -- lexicographic comparison
else
local h = getcomphandler(op1, op2, "__le")
if h then
return h(op1, op2)
else
h = getcomphandler(op1, op2, "__lt")
if h then
return not h(op2, op1)
else
error(...);
end
end
end
end
a >= b
等价于 b <= a
。请注意,在没有 "le" 元方法的情况下,Lua 会尝试 "lt",假设 a <= b
等价于 not (b < a)
。table[key]
。function gettable_event (table, key)
local h
if type(table) == "table" then
local v = rawget(table, key)
if v ~= nil then return v end
h = metatable(table).__index
if h == nil then return nil end
else
h = metatable(table).__index
if h == nil then
error(...);
end
end
if type(h) == "function" then
return h(table, key) -- call the handler
else return h[key] -- or repeat operation on it
end
table[key] = value
。function settable_event (table, key, value)
local h
if type(table) == "table" then
local v = rawget(table, key)
if v ~= nil then rawset(table, key, value); return end
h = metatable(table).__newindex
if h == nil then rawset(table, key, value); return end
else
h = metatable(table).__newindex
if h == nil then
error(...);
end
end
if type(h) == "function" then
return h(table, key,value) -- call the handler
else h[key] = value -- or repeat operation on it
end
function function_event (func, ...)
if type(func) == "function" then
return func(...) -- primitive call
else
local h = metatable(func).__call
if h then
return h(func, ...)
else
error(...)
end
end
end
setfenv
来更改 Lua 函数或正在运行线程的环境。你可以通过调用 getfenv
(参见 lua_getfenv())来获取 Lua 函数或正在运行线程的环境。要操作其他对象的環境(用户数据、C 函数、其他线程),你必须使用 C API。lua_gc
(参见 lua_gc())或在 Lua 中调用 collectgarbage
(参见 collectgarbage())来更改这些数字。两者都以百分比作为参数(因此参数 100 表示实际值为 1)。使用这些函数,你还可以直接控制收集器(例如,停止和重新启动它)。__gc
字段的垃圾用户数据不会立即被垃圾收集器收集。相反,Lua 会将它们放到一个列表中。在收集之后,Lua 会对该列表中的每个用户数据执行以下函数的等效操作function gc_event (udata)
local h = metatable(udata).__gc
if h then
h(udata)
end
end
__mode
字段的值控制。如果 __mode
字段是一个包含字符 k
的字符串,则表中的键是弱的。如果 __mode
包含 v
,则表中的值是弱的。__mode
字段的值。否则,由该元表控制的表的弱行为将是未定义的。coroutine.create
来创建一个协程(参见 coroutine.create())。它的唯一参数是一个函数,它是协程的主函数。create
函数只创建一个新的协程并返回指向它的句柄(一个 thread
类型的对象);它不会启动协程执行。coroutine.resume
(参见 coroutine.resume())时,将 coroutine.create
返回的线程作为其第一个参数传递,协程将开始其执行,从其主函数的第一行开始。传递给 coroutine.resume
的额外参数将传递给协程主函数。协程开始运行后,它会一直运行,直到它终止或 yield
。coroutine.resume
返回 true
,以及协程主函数返回的任何值。在发生错误的情况下,coroutine.resume
返回 false
和一个错误消息。coroutine.yield
(参见 coroutine.yield())来挂起。当协程挂起时,相应的 coroutine.resume
会立即返回,即使挂起发生在嵌套函数调用中(也就是说,不是在主函数中,而是在直接或间接由主函数调用的函数中)。在挂起的情况下,coroutine.resume
也返回 true
,以及传递给 coroutine.yield
的任何值。下次您恢复同一个协程时,它会从挂起的地方继续执行,coroutine.yield
的调用会返回传递给 coroutine.resume
的任何额外参数。coroutine.create
一样,coroutine.wrap
函数(参见 coroutine.wrap())也创建了一个协程,但它不是返回协程本身,而是返回一个函数,当该函数被调用时,会恢复协程。传递给此函数的任何参数都会作为额外参数传递给 coroutine.resume
。coroutine.wrap
返回 coroutine.resume
返回的所有值,除了第一个(布尔错误代码)。与 coroutine.resume
不同,coroutine.wrap
不捕获错误;任何错误都会传播给调用者。function foo1 (a)
print("foo", a)
return coroutine.yield(2*a)
end
co = coroutine.create(function (a,b)
print("co-body", a, b)
local r = foo1(a+1)
print("co-body", r)
local r, s = coroutine.yield(a+b, a-b)
print("co-body", r, s)
return b, "end"
end)
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"))
co-body 1 10 foo 2 main true 4 co-body r main true 11 -9 co-body x y main true 10 end main false cannot resume dead coroutine
lua.h
中声明。宏
提供。所有这些宏都使用每个参数恰好一次(除了第一个参数,它始终是 Lua 状态),因此不会产生隐藏的副作用。luaconf.h
中为宏 luai_apicheck
编译 Lua 来更改此行为。nil
、数字、字符串等)。n
个元素,那么索引 1 表示第一个元素(即,最先被推送到堆栈上的元素),索引 n
表示最后一个元素;索引 -1
也表示最后一个元素(即,位于顶部的元素),索引 -n
表示第一个元素。我们说一个索引是有效的,如果它在 1 到堆栈顶部之间(即,如果 1 <= abs(index) <= top
)。lua_checkstack
函数来增加堆栈大小(参见 lua_checkstack())。LUA_MINSTACK
个堆栈位置可用。LUA_MINSTACK
定义为 20,因此通常您不必担心堆栈空间,除非您的代码有将元素推送到堆栈上的循环。lua_checkstack
设置的最大堆栈大小。这些索引称为可接受索引。更正式地说,我们将可接受索引定义如下(index < 0 && abs(index) <= top) || (index > 0 && index <= stackspace)
LUA_GLOBALSINDEX
。运行的 C 函数的环境始终位于伪索引 LUA_ENVIRONINDEX
。lua_getfield(L, LUA_GLOBALSINDEX, varname);
lua_upvalueindex
生成。与函数关联的第一个值位于位置 lua_upvalueindex(1)
,依此类推。对 lua_upvalueindex(
n
)
的任何访问,其中 n
大于当前函数的上值数量,都会产生一个可接受的(但无效的)索引。LUA_REGISTRYINDEX
。任何 C 库都可以将数据存储到此表中,但应注意选择与其他库使用的键不同的键,以避免冲突。通常,您应该使用一个包含您的库名称的字符串或一个带有 C 代码中 C 对象地址的轻量级用户数据作为键。longjmp
机制来处理错误。(如果您使用 C++,您也可以选择使用异常;参见文件 luaconf.h
。)当 Lua 遇到任何错误(例如内存分配错误、类型错误、语法错误和运行时错误)时,它会引发错误;也就是说,它会进行长跳转。受保护的环境使用 setjmp
来设置恢复点;任何错误都会跳转到最近的活动恢复点。lua_newstate
、lua_close
、lua_load
、lua_pcall
和 lua_cpcall
(参见 lua_newstate()、lua_close()、lua_load()、lua_pcall() 和 lua_cpcall())。lua_error
(参见 lua_error())来引发错误。realloc
的功能,但并不完全相同。它的参数是ud
,一个传递给lua_newstate
的不透明指针(参见 lua_newstate());ptr
,指向正在分配/重新分配/释放的块的指针;osize
,块的原始大小;nsize
,块的新大小。当ptr
为NULL
时,当且仅当osize
为零。当nsize
为零时,分配器必须返回NULL
;如果osize
不为零,它应该释放ptr
指向的块。当nsize
不为零时,分配器当且仅当它无法满足请求时返回NULL
。当nsize
不为零且osize
为零时,分配器应该像malloc
一样工作。当nsize
和osize
不为零时,分配器像realloc
一样工作。Lua 假设分配器在osize >= nsize
时永远不会失败。luaL_newstate
使用(参见 luaL_newstate())。static void *l_alloc (void *ud, void *ptr, size_t osize,
size_t nsize) {
(void)ud; (void)osize; /* not used */
if (nsize == 0) {
free(ptr);
return NULL;
}
else
return realloc(ptr, nsize);
}
free(NULL)
没有效果,并且realloc(NULL, size)
等同于malloc(size)
。ANSI C 确保这两种行为。panic
function
,然后调用exit(EXIT_FAILURE)
,从而退出主机应用程序。你的恐慌函数可以通过永不返回来避免此退出(例如,进行长跳转)。lua_call
;nargs
是你压入栈的参数个数。当函数被调用时,所有参数和函数值都会从栈中弹出。函数结果在函数返回时压入栈。结果数将调整为nresults
,除非nresults
是LUA_MULTRET
。在这种情况下,将压入函数的all
结果。Lua 会确保返回的值适合栈空间。函数结果按直接顺序压入栈(第一个结果先压入栈),因此在调用之后,最后一个结果位于栈顶。longjmp
)。a = f("how", t.x, 14)
lua_getfield(L, LUA_GLOBALSINDEX, "f"); // function to be called
lua_pushstring(L, "how"); // 1st argument
lua_getfield(L, LUA_GLOBALSINDEX, "t"); // table to be indexed
lua_getfield(L, -1, "x"); // push result of t.x (2nd arg)
lua_remove(L, -2); // remove 't' from the stack
lua_pushinteger(L, 14); // 3rd argument
lua_call(L, 3, 1); // call 'f' with 3 arguments and 1 result
lua_setfield(L, LUA_GLOBALSINDEX, "a"); // set global 'a'
lua_gettop(L)
(参见 lua_gettop())返回函数接收的参数个数。第一个参数(如果有)位于索引 1 处,最后一个参数位于索引 lua_gettop(L)
处。要将值返回给 Lua,C 函数只需将它们压入栈,以直接顺序(第一个结果先压入栈),并返回结果个数。栈中结果下方任何其他值都会被 Lua 正确丢弃。与 Lua 函数一样,由 Lua 调用的 C 函数也可以返回多个结果。static int foo (lua_State *L) {
int n = lua_gettop(L); /* number of arguments */
lua_Number sum = 0;
int i;
for (i = 1; i <= n; i++) {
if (!lua_isnumber(L, i)) {
lua_pushstring(L, "incorrect argument");
lua_error(L);
}
sum += lua_tonumber(L, i);
}
lua_pushnumber(L, sum/n); /* first result */
lua_pushnumber(L, sum); /* second result */
return 2; /* number of results */
}
extra
个空闲栈槽。如果它无法将栈扩展到该大小,则返回 false。此函数从不缩小栈;如果栈已经大于新大小,则它保持不变。n
个值,弹出它们,并将结果留在栈顶。如果n
为 1,则结果为栈上的单个字符串(即,函数不执行任何操作);如果n
为 0,则结果为空字符串。连接操作遵循 Lua 的通常语义(参见 lua-concat)。func
。func
在其栈中只包含一个元素,一个包含ud
的轻量级用户数据。如果发生错误,lua_cpcall
将返回与lua_pcall
相同的错误代码(参见 lua_pcall()),以及栈顶的错误对象;否则,它返回零,并且不改变栈。func
返回的所有值都会被丢弃。narr
个数组元素和nrec
个非数组元素的空间。当你确切知道表将包含多少个元素时,这种预分配很有用。否则,你可以使用函数lua_newtable
(参见 lua_newtable())。lua_dump
会调用函数writer
(参见 lua_Writer)并使用给定的data
来写入它们。index1
和index2
处的两个值相等,则返回 1,遵循 Lua ==
运算符的语义(即,可能调用元方法)。否则返回 0。如果任何索引无效,也返回 0。what
的值执行多个任务LUA_GCSTOP
停止垃圾收集器。LUA_GCRESTART
重新启动垃圾收集器。LUA_GCCOLLECT
执行一个完整的垃圾收集循环。LUA_GCCOUNT
返回 Lua 当前使用的内存量(以 KB 为单位)。LUA_GCCOUNTB
返回 Lua 当前使用的内存字节数除以 1024 后的余数。LUA_GCSTEP
执行垃圾收集的增量步骤。步骤“大小”由data
控制(较大的值意味着更多步骤),方式未指定。如果你想控制步骤大小,你必须通过实验调整data
的值。如果步骤完成了一个垃圾收集循环,则函数返回 1。name
的值压入栈。它被定义为宏#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, s)
t[k]
的值压入栈,其中t
是给定有效索引index
处的值,而k
是栈顶的值。ptrdiff_t
,通常是机器“舒适地”处理的最大整型。nil
,则返回 1,否则返回 0。index1
处的值小于可接受索引 index2
处的值,则返回 1,遵循 Lua <
运算符的语义(即,可能会调用元方法)。否则返回 0。如果任何索引无效,也返回 0。int lua_load (lua_State *L,
lua_Reader reader,
void *data,
const char *chunkname);
lua_load
会将编译后的代码块作为 Lua 函数压入堆栈顶端。否则,它会压入一个错误消息。lua_load
的返回值为0
: 没有错误;LUA_ERRSYNTAX
: 预编译期间的语法错误;LUA_ERRMEM
: 内存分配错误。lua_load
会自动检测代码块是文本还是二进制文件,并相应地加载它(参见程序 luac
)。chunkname
参数为代码块提供一个名称,该名称用于错误消息和调试信息(参见 lua-apiDebug)。NULL
。参数 f
是分配器函数;Lua 通过此函数完成此状态的所有内存分配。第二个参数 ud
是一个不透明的指针,Lua 在每次调用分配器时都会简单地传递给它。lua_createtable(L, 0, 0)
(参见 lua_createtable())。lua_State
(参见 lua_State)的指针,该指针表示此新线程。此函数返回的新状态与原始状态共享所有全局对象(例如表),但具有独立的执行堆栈。gc
元方法的完整用户数据时,Lua 会调用元方法并标记用户数据为已完成。当此用户数据再次被收集时,Lua 会释放其相应的内存。lua_next
返回 0(并且不压入任何内容)。/* table is in the stack at index 't' */
lua_pushnil(L); /* first key */
while (lua_next(L, t) != 0) {
/* uses 'key' (at index -2) and 'value' (at index -1) */
printf("%s - %s\n",
lua_typename(L, lua_type(L, -2)),
lua_typename(L, lua_type(L, -1)));
/* removes 'value'; keeps 'key' for next iteration */
lua_pop(L, 1);
}
lua_tolstring
(参见 lua_tolstring()),除非您知道键实际上是字符串。请记住,lua_tolstring
会更改
给定索引处的值;这会混淆对 lua_next
的下一次调用。luaconf.h
中更改。#
)的结果;对于用户数据,这是为用户数据分配的内存块的大小;对于其他值,它是 0。nargs
和 nresults
的含义与 lua_call
中相同(参见 lua_call())。如果调用期间没有错误,lua_pcall
的行为与 lua_call
完全相同。但是,如果发生任何错误,lua_pcall
会捕获它,在堆栈上压入一个值(错误消息),并返回一个错误代码。与 lua_call
一样,lua_pcall
始终从堆栈中删除函数及其参数。errfunc
为 0,则堆栈上返回的错误消息正是原始错误消息。否则,errfunc
是 error
处理程序函数
的堆栈索引。(在当前实现中,此索引不能是伪索引。)在运行时错误的情况下,此函数将使用错误消息被调用,其返回值将是 lua_pcall
在堆栈上返回的消息。lua_pcall
返回后,无法收集此类信息,因为到那时堆栈已经展开。lua_pcall
函数在成功的情况下返回 0,或返回以下错误代码之一(在 lua.h
中定义)LUA_ERRRUN
运行时错误。LUA_ERRMEM
内存分配错误。对于此类错误,Lua 不会调用错误处理程序函数。LUA_ERRERR
在运行错误处理程序函数时出错。n
个元素。b
的布尔值压入堆栈。lua_pushcclosure
来创建并压入 C 函数到堆栈中,参数 n
表示应与函数关联多少个值。lua_pushcclosure
还会从堆栈中弹出这些值。function
的 Lua 值压入堆栈,当调用该值时,会调用相应的 C 函数。lua_pushcfunction
被定义为一个宏#define lua_pushcfunction(L,f) lua_pushcclosure(L,f,0)
sprintf
,但有一些重要的区别%%
(在字符串中插入 %
)、%s
(插入一个以零结尾的字符串,没有大小限制)、%f
(插入一个 lua_Number
)、%p
(将指针作为十六进制数插入)、%d
(插入一个 int
)和 %c
(将 int
作为字符插入)。n
的数字压入堆栈。s
指向的字符串(大小为 len
)压入堆栈。Lua 会对给定字符串进行(或重复使用)内部副本,因此在函数返回后可以立即释放或重复使用 s
处的内存。字符串可以包含嵌入的零。n
的数字压入堆栈。s
指向的以零结尾的字符串压入堆栈。Lua 会对给定字符串进行(或重复使用)内部副本,因此在函数返回后可以立即释放或重复使用 s
处的内存。字符串不能包含嵌入的零;假定它在第一个零处结束。L
表示的线程压入堆栈。如果此线程是其状态的主线程,则返回 1。const char *lua_pushvfstring (lua_State *L,
const char *fmt,
va_list argp);
index1
和 index2
中的两个值在原始上相等(即,不调用元方法),则返回 1。否则返回 0。如果任何索引无效,也返回 0。lua_gettable
(参见 lua_gettable()),但执行的是原始访问(即,不使用元方法)。t[n]
的值推送到堆栈上,其中 t
是给定有效索引 index
处的 value。访问是原始的;也就是说,它不调用元方法。lua_settable
(参见 lua_settable()),但执行的是原始赋值(即,不使用元方法)。t[n] = v
的操作,其中 t
是给定有效索引 index
处的 value,而 v
是堆栈顶部的 value。lua_load
(参见 lua_load())使用的 reader 函数。每次需要 chunk 的另一部分时,lua_load
都会调用 reader,并将它的 data
参数传递过去。reader 必须返回指向包含 chunk 新部分的内存块的指针,并将 size
设置为块的大小。该块必须存在,直到再次调用 reader 函数。为了指示 chunk 的结束,reader 必须返回 NULL
。reader 函数可以返回任何大小大于零的块。f
设置为全局 name
的新 value。它被定义为宏#define lua_register(L,n,f) \
(lua_pushcfunction(L, f), lua_setglobal(L, n))
lua_resume
(参见 lua_resume()),其中 narg
是参数的数量。此调用在协程挂起或完成执行时返回。当它返回时,堆栈包含传递给 lua_yield
(参见 lua_yield())的所有 value,或主体函数返回的所有 value。lua_resume
如果协程挂起,则返回 LUA_YIELD
;如果协程在没有错误的情况下完成执行,则返回 0;如果出现错误,则返回错误代码(参见 lua_pcall())。在发生错误的情况下,堆栈不会被展开,因此您可以使用调试 API 对其进行操作。错误消息位于堆栈的顶部。要重新启动协程,只需将作为 lua_yield
结果传递的 value 放入其堆栈中,然后调用 lua_resume
。f
,用户数据为 ud
。lua_setfenv
返回 0。否则它返回 1。t[k] = v
的操作,其中 t
是给定有效索引 index
处的 value,而 v
是堆栈顶部的 value。name
的新 value。它被定义为宏#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, s)
t[k] = v
的操作,其中 t
是给定有效索引 index
处的 value,v
是堆栈顶部的 value,而 k
是紧邻顶部的 value。nil
。如果 index
为 0,则所有堆栈元素都将被移除。lua_newstate
(参见 lua_newstate()),它从头开始创建 Lua 状态。L
的状态。LUA_YIELD
。lua_toboolean
对任何与 false
和 nil
不同的 Lua value 返回 1;否则它返回 0。它在使用非有效索引调用时也返回 0。(如果您只希望接受实际的布尔值,请使用 lua_isboolean
lua_isboolean() 来测试 value 的类型。)NULL
。lua_Integer
(参见 lua_Integer)。Lua value 必须是数字或可以转换为数字的字符串(参见 lua-coercion);否则,lua_tointeger
返回 0。len
不为 NULL
,它还会将 *len
设置为字符串长度。Lua value 必须是字符串或数字;否则,函数返回 NULL
。如果 value 是数字,则 lua_tolstring
还 更改堆栈中实际的 value 为
字符串
。(当对遍历表格期间的键应用 lua_tolstring
时,此更改会使 lua_next
lua_next() 变得混乱。)lua_tolstring
返回指向 Lua 状态内字符串的完全对齐指针。此字符串在其最后一个字符之后始终包含一个零 (\0
)(如 C 中一样),但其主体中可能包含其他零。由于 Lua 有垃圾回收,因此无法保证 lua_tolstring
返回的指针在相应的 value 从堆栈中移除后仍然有效。lua_Number
(参见 lua_Number)。Lua value 必须是数字或可以转换为数字的字符串(参见 lua-coercion);否则,lua_tonumber
返回 0。void*
)。value 可以是用户数据、表格、线程或函数;否则,lua_topointer
返回 NULL
。不同的对象将给出不同的指针。无法将指针转换回其原始 value。NULL
。LUA_TNONE
(即,指向“空”堆栈位置的索引)。lua_type
返回的类型由 lua.h
中定义的以下常量编码:LUA_TNIL
、LUA_TNUMBER
、LUA_TBOOLEAN
、LUA_TSTRING
、LUA_TTABLE
、LUA_TFUNCTION
、LUA_TUSERDATA
、LUA_TTHREAD
和 LUA_TLIGHTUSERDATA
。tp
编码的类型的名称,tp
必须是 lua_type
返回的值之一。lua_dump
(参见 lua_dump())使用的 writer 函数。每次生成 chunk 的另一部分时,lua_dump
都会调用 writer,并将要写入的缓冲区 (p
)、其大小 (sz
) 以及传递给 lua_dump
的 data
参数传递过去。lua_dump
再次调用 writer。相同
全局状态的不同线程之间交换值。from
中弹出n
个值,并将它们推送到堆栈to
上。return lua_yield (L, nresults);
lua_yield
时,正在运行的协程会暂停执行,并且调用启动此协程的lua_resume
(参见 lua_resume())会返回。参数nresults
是作为结果传递给lua_resume
的堆栈中值的个数。10 20 30 40 50*
开始(从底部到顶部;*
标记顶部),那么lua_pushvalue(L, 3) --> 10 20 30 40 50 30* lua_pushvalue(L, -1) --> 10 20 30 40 50 30 30* lua_remove(L, -3) --> 10 20 30 40 30 30* lua_remove(L, 6) --> 10 20 30 40 30* lua_insert(L, 1) --> 30 10 20 30 40* lua_insert(L, -1) --> 30 10 20 30 40* (no effect) lua_replace(L, 2) --> 30 40 20 30* lua_settop(L, -3) --> 30 40* lua_settop(L, 6) --> 30 40 nil nil nil nil*
typedef struct lua_Debug {
int event;
const char *name; /* (n) */
const char *namewhat; /* (n) */
const char *what; /* (S) */
const char *source; /* (S) */
int currentline; /* (l) */
int nups; /* (u) number of upvalues */
int linedefined; /* (S) */
int lastlinedefined; /* (S) */
char short_src[LUA_IDSIZE]; /* (S) */
/* private part */
other fields
} lua_Debug;
lua_getstack
(参见 lua_getstack())只填充此结构的私有部分,以便以后使用。要使用有用的信息填充lua_Debug
的其他字段,请调用lua_getinfo
(参见 lua_getinfo())。lua_Debug
的字段具有以下含义source
如果函数是在字符串中定义的,那么source
就是该字符串。如果函数是在文件中定义的,那么source
以@
开头,后跟文件名。short_src
source
的可“打印”版本,用于错误消息。linedefined
函数定义开始的行号。lastlinedefined
函数定义结束的行号。what
如果函数是 Lua 函数,则为字符串"Lua"
;如果它是 C 函数,则为"C"
;如果它是块的主体部分,则为"main"
;如果它是进行了尾调用函数,则为"tail"
。在后一种情况下,Lua 没有有关该函数的其他信息。currentline
给定函数正在执行的当前行。当没有行信息可用时,currentline
被设置为-1。name
给定函数的合理名称。因为 Lua 中的函数是一等公民,所以它们没有固定的名称:一些函数可能是多个全局变量的值,而另一些函数可能只存储在表字段中。lua_getinfo
函数检查函数是如何调用的,以找到一个合适的名称。如果它找不到名称,则name
被设置为NULL
。namewhat
解释name
字段。namewhat
的值可以是"global"
、"local"
、"method"
、"field"
、"upvalue"
或""
(空字符串),具体取决于函数是如何调用的。(Lua 在没有其他选项适用时使用空字符串。)nups
函数的上值个数。what
字符串的开头字符设置为>
。(在这种情况下,lua_getinfo
会弹出堆栈顶部的函数。)例如,要了解函数f
是在哪一行定义的,您可以编写以下代码lua_Debug ar;
lua_getfield(L, LUA_GLOBALSINDEX, "f"); /* get global '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
'u'
填充字段nups
'f'
将正在给定级别运行的函数推送到堆栈上 'L'
将一个表推送到堆栈上,该表的索引是函数中有效行的行号。(有效行
是指与一些相关代码关联的行,即可以放置断点的行。非有效行包括空行和注释。)what
中的选项无效)。ar
必须是有效的激活记录,该记录由先前对lua_getstack
(参见 lua_getstack())的调用填充,或者作为钩子的参数给出(参见 lua_Hook)。索引n
选择要检查的局部变量(1 是第一个参数或活动的局部变量,依此类推,直到最后一个活动的局部变量)。lua_getlocal
将变量的值推送到堆栈上并返回它的名称。(
(左括号)开头的变量名称代表内部变量(循环控制变量、临时变量和 C 函数局部变量)。NULL
(并且不推送到堆栈上)。激活记录
的标识填充lua_Debug
(参见 lua_Debug)结构的部分内容。级别 0 是当前正在运行的函数,而级别n+1
是调用了级别n
的函数。当没有错误时,lua_getstack
返回 1;当使用大于堆栈深度的级别调用时,它返回 0。lua_getupvalue
获取上值的索引n
,将上值的值推送到堆栈上,并返回它的名称。funcindex
指向堆栈中的闭包。(上值没有特定的顺序,因为它们在整个函数中都是活动的。因此,它们按任意顺序编号。)NULL
(并且不推送到堆栈上)。对于 C 函数,此函数使用空字符串""
作为所有上值的名称。ar
参数的字段event
都会设置为触发钩子的特定事件。Lua 使用以下常量来标识这些事件:LUA_HOOKCALL
、LUA_HOOKRET
、LUA_HOOKTAILRET
、LUA_HOOKLINE
和LUA_HOOKCOUNT
。此外,对于行事件,字段currentline
也会被设置。要获取ar
中任何其他字段的值,钩子必须调用lua_getinfo
(参见 lua_getinfo())。对于返回事件,event
可能是LUA_HOOKRET
(正常值)或LUA_HOOKTAILRET
。在后一种情况下,Lua 正在模拟从进行了尾调用的函数的返回;在这种情况下,调用lua_getinfo
是无用的。f
是钩子函数。mask
指定在哪些事件上调用钩子:它是由常量LUA_MASKCALL
、LUA_MASKRET
、LUA_MASKLINE
和LUA_MASKCOUNT
的按位或
运算形成的。count
参数只有在掩码包含LUA_MASKCOUNT
时才有意义。对于每个事件,钩子的调用方式如下所示调用钩子
:在解释器调用函数时被调用。钩子在 Lua 进入新函数后立即被调用,在函数获取其参数之前。返回钩子
:在解释器从函数返回时被调用。钩子在 Lua 离开函数之前立即被调用。您无法访问函数要返回的值。行钩子
:在解释器即将开始执行新代码行或跳转回代码中(即使是跳转到同一行)时被调用。(此事件仅在 Lua 正在执行 Lua 函数时发生。)计数钩子
:在解释器每执行count
条指令后被调用。(此事件仅在 Lua 正在执行 Lua 函数时发生。)mask
设置为零来禁用钩子。ar
和n
与lua_getlocal
(参见 lua_getlocal())中的一样。lua_setlocal
将堆栈顶部的值分配给变量并返回它的名称。它还会从堆栈中弹出值。NULL
(并且不弹出任何内容)。NULL
(并且不弹出任何内容)。int listvars (lua_State *L, int level) {
lua_Debug ar;
int i;
const char *name;
if (lua_getstack(L, level, &ar) == 0)
return 0; /* failure: no such level in the stack */
i = 1;
while ((name = lua_getlocal(L, &ar, i++)) != NULL) {
printf("local %d %s\n", i-1, name);
lua_pop(L, 1); /* remove variable value */
}
lua_getinfo(L, "f", &ar); /* retrieves function */
i = 1;
while ((name = lua_getupvalue(L, -1, i++)) != NULL) {
printf("upvalue %d %s\n", i-1, name);
lua_pop(L, 1); /* remove upvalue value */
}
return 1;
}
lauxlib.h
中定义,并且具有前缀luaL_
。luaL_check*
或 luaL_opt*
。如果检查不满足,所有这些函数都会引发错误。由于错误消息是针对参数格式化的(例如,“错误参数 #1”),因此不应将这些函数用于其他堆栈值。B
(参见 luaL_Buffer)。弹出该值。void luaL_argcheck (lua_State *L,
int cond,
int narg,
const char *extramsg);
cond
是否为真。如果不是,则使用以下消息引发错误,其中 func
从调用堆栈中检索bad argument #<narg> to <func> (<extramsg>)
func
从调用堆栈中检索bad argument #<narg> to <func> (<extramsg>)
return luaL_argerror(
args
)
是一个惯例。字符串缓冲区
的类型。luaL_Buffer
的变量 b
。luaL_buffinit(L, &b)
初始化它(参见 luaL_buffinit())。luaL_add*
函数将字符串片段添加到缓冲区。luaL_pushresult(&b)
(参见 luaL_pushresult())。此调用将最终字符串留在堆栈顶部。luaL_addvalue
luaL_addvalue()。)在调用 luaL_pushresult
后,堆栈将返回到初始化缓冲区时的级别,加上其顶部的最终字符串。B
。此函数不会分配任何空间;缓冲区必须声明为变量(参见 luaL_Buffer)。obj
处的对象具有元表,并且此元表具有字段 e
,则此函数将调用此字段并将对象作为其唯一参数传递。在这种情况下,此函数返回 1 并将调用返回的值推送到堆栈中。如果没有元表或没有元方法,则此函数返回 0(不将任何值推送到堆栈中)。narg
处具有任何类型的参数(包括 nil
)。narg
是否为数字,并返回此数字转换为 int
。narg
是否为数字,并返回此数字转换为 long
。const char *luaL_checklstring (lua_State *L, int narg, size_t *l);
narg
是否为字符串并返回此字符串;如果 l
不为 NULL
,则将 *l
填充为字符串的长度。narg
是否为数字,并返回此数字(参见 lua_Number)。int luaL_checkoption (lua_State *L,
int narg,
const char *def,
const char *const lst[]);
narg
是否为字符串,并在数组 lst
(必须以 NULL 结尾)中搜索此字符串。返回数组中找到字符串的索引。如果参数不是字符串或无法找到字符串,则引发错误。def
不为 NULL
,则当没有参数 narg
或此参数为 nil
时,该函数使用 def
作为默认值。top + sz
个元素,如果堆栈无法扩展到该大小,则引发错误。msg
是添加到错误消息中的附加文本。narg
是否为字符串并返回此字符串。void *luaL_checkudata (lua_State *L, int narg, const char *tname);
(luaL_loadfile(L, filename) || lua_pcall(L, 0, LUA_MULTRET, 0))
(luaL_loadstring(L, str) || lua_pcall(L, 0, LUA_MULTRET, 0))
fmt
加上任何额外的参数给出,遵循 lua_pushfstring
的相同规则(参见 lua_pushfstring())。它还在消息开头添加了发生错误的文件名和行号,如果此信息可用。return luaL_error(
args
)
是一个惯例。obj
处的对象元表中的字段 e
推送到堆栈中。如果对象没有元表,或者元表没有此字段,则返回 0 且不推入任何内容。tname
关联的元表推送到堆栈中(参见 luaL_newmetatable())。const char *luaL_gsub (lua_State *L,
const char *s,
const char *p,
const char *r);
p
的任何出现替换为字符串 r
来创建字符串 s
的副本。将生成的字符串推送到堆栈并返回它。int luaL_loadbuffer (lua_State *L,
const char *buff,
size_t sz,
const char *name);
lua_load
相同的结果。name
是代码块名称,用于调试信息和错误消息。lua_load
(参见 lua_load())加载名为 filename
的文件中的代码块。如果 filename
为 NULL
,则从标准输入加载。如果文件的第一行以 #
开头,则忽略该行。lua_load
相同的结果,但如果无法打开/读取文件,则具有额外的错误代码 LUA_ERRFILE
。lua_load
一样,此函数仅加载代码块;它不运行它。lua_load
相同的结果。lua_load
一样,此函数仅加载代码块;它不运行它。tname
,则返回 0。否则,创建一个新表用作用户数据的元表,将其添加到注册表中,键为 tname
,并返回 1。tname
关联的值推送到堆栈中。lua_Integer luaL_optinteger (lua_State *L,
int narg,
lua_Integer d);
const char *luaL_optlstring (lua_State *L,
int narg,
const char *d,
size_t *l);
void luaL_register (lua_State *L,
const char *libname,
const luaL_Reg *l);
location
: bad argument
narg
to
'func'
(
tname
expected, got
rt
)
chunkname:currentline
{v}
[, {message}
]) assert()"stop"
停止垃圾回收器。"restart"
重新启动垃圾回收器。"collect"
执行完整的垃圾回收周期。"count"
返回 Lua 使用的总内存(以 KB 为单位)。"step"
执行垃圾回收步骤。步骤“大小”由 `{arg}` 控制(较大的值意味着更多步骤),以未指定的方式进行。如果您想控制步骤大小,则必须通过实验调整 `{arg}` 的值。如果步骤完成了一个收集周期,则返回 `true`。"setpause"
将 `{arg}` /100 设置为收集器 `pause` 的新值(参见 lua-gc)。"setstepmul"
将 `{arg}` /100 设置为收集器 `step multiplier` 的新值(参见 lua-gc)。{filename}
) dofile()stdin
) 的内容。返回代码块返回的所有值。如果发生错误,`dofile` 会将错误传播到其调用者(即,`dofile` 不会在受保护模式下运行)。{f}
) getfenv(){object}
) getmetatable(){object}
没有元表,则返回nil
。 否则,如果对象的元表具有"__metatable"
字段,则返回关联的值。 否则,返回给定对象的元表。for i,v in ipairs(t) do
body
end
1,t[1]
),(2,t[2]
),...,直到表中第一个缺失的整数键。{func}
[, {chunkname}
]) load(){func}
加载一个块以获取其片段。 对{func}
的每次调用都必须返回一个字符串,该字符串与之前的结果连接。 返回nil
(或无值)表示块的结束。nil
以及错误消息。 返回函数的环境是全局环境。{chunkname}
用作错误消息和调试信息的块名称。assert(loadstring(s))()
{table}
[, {index}
]) next()next
返回表的下一个索引及其关联的值。 当以nil
作为其第二个参数调用时,next
返回初始索引及其关联的值。 当以最后一个索引或在空表中以nil
调用时,next
返回nil
。 如果第二个参数不存在,则将其解释为nil
。 特别是,您可以使用next(t)
来检查表是否为空。for
或ipairs()函数。)next
的行为是未定义
的。 然而,您可以修改现有字段。 特别是,您可以清除现有字段。for k,v in pairs(t) do
body
end
{t}
的所有键值对。{f}
, {arg1}
, {...}
) pcall()保护模式
下使用给定的参数调用函数{f}
。 这意味着{f}
内部的任何错误都不会传播;相反,pcall
捕获错误并返回一个状态代码。 它的第一个结果是状态代码(一个布尔值),如果调用成功且没有错误,则为true
。 在这种情况下,pcall
还会在第一个结果之后返回调用中的所有结果。 在发生任何错误的情况下,pcall
返回false
以及错误消息。{...}
) print()stdout
,使用tostring
tostring()函数将它们转换为字符串。 print
并非旨在用于格式化输出,而仅仅是一种快速显示值的方法,通常用于调试。 对于格式化输出,请使用string.format
(参见 string.format())。{table}
, {index}
, {value}
) rawset()table[index]
的实际值设置为{value}
,不调用任何元方法。 {table}
必须是一个表,{index}
任何与nil
不同的值,{value}
任何 Lua 值。{table}
。{index}
, {...}
) select(){index}
是数字,则返回参数编号{index}
之后的所有参数。 否则,{index}
必须是字符串"#"
,并且select
返回它接收的额外参数的总数。{f}
, {table}
) setfenv(){f}
可以是 Lua 函数,也可以是指定该堆栈级别上函数的数字:级别 1 是调用setfenv
的函数。 setfenv
返回给定的函数。{f}
为 0 时,setfenv
更改运行线程的环境。 在这种情况下,setfenv
不返回值。{table}
, {metatable}
) setmetatable(){metatable}
为nil
,则删除给定表的元表。 如果原始元表具有"__metatable"
字段,则会引发错误。{table}
。A
(大小写均可)表示 10,B
表示 11,依此类推,Z'
表示 35。 在基数 10(默认值)中,数字可以有小数部分,以及可选的指数部分(参见 lua-lexical)。 在其他基数中,只接受无符号整数。{e}
) tostring()string.format
(参见 string.format())。{v}
) lua-type()"nil"
(一个字符串,而不是值nil
),"number"
,"string"
,"boolean
,"table"
,"function"
,"thread"
和"userdata"
。xpcall
在保护模式下调用函数{f}
,使用{err}
作为错误处理程序。 {f}
内部的任何错误都不会传播;相反,xpcall
捕获错误,使用原始错误对象调用{err}
函数,并返回一个状态代码。 它的第一个结果是状态代码(一个布尔值),如果调用成功且没有错误,则为 true。 在这种情况下,xpcall
还会在第一个结果之后返回调用中的所有结果。 在发生任何错误的情况下,xpcall
返回false
以及{err}
的结果。coroutine
中。 有关协程的常规描述,请参见 lua-coroutine。{co}
[, {val1}
, {...}
]) coroutine.resume(){co}
的执行。 第一次恢复协程时,它将开始运行其主体。 值{val1}
,{...}
作为参数传递给主体函数。 如果协程已让出,则resume
会重新启动它;值{val1}
,{...}
作为让出的结果传递。resume
返回true
以及传递给yield
的任何值(如果协程让出)或主体函数返回的任何值(如果协程终止)。 如果有任何错误,resume
返回false
以及错误消息。{co}
) coroutine.status(){co}
的状态,作为字符串:"running"
,如果协程正在运行(即,它调用了status
);"suspended"
,如果协程已暂停在对yield
的调用中,或者它尚未开始运行;"normal"
,如果协程处于活动状态但未运行(即,它已恢复另一个协程);以及"dead"
,如果协程已完成其主体函数,或者它已停止并出现错误。{f}
) coroutine.wrap(){f}
。 {f}
必须是 Lua 函数。 返回一个函数,该函数每次被调用时都会恢复协程。 传递给函数的任何参数都将作为对resume
的额外参数进行处理。 返回resume
返回的相同值,除了第一个布尔值。 在发生错误的情况下,传播错误。{...}
) coroutine.yield()yield
的任何参数都将作为对resume
的额外结果传递。require
和 module
(参见 require() 和 module())。其他所有内容都导出到表 package
中。{name}
[, {...}
]) module()package.loaded[name]
中存在一个表,则此表为模块。否则,如果存在具有给定名称的全局表 t
,则此表为模块。否则,创建一个新表 t
并将其设置为全局 {name}
的值和 package.loaded[name]
的值。此函数还将 t._NAME
初始化为给定名称,将 t._M
初始化为模块(t
本身),并将 t._PACKAGE
初始化为包名称(完整模块名称减去最后一个组件;见下文)。最后,module
将 t
设置为当前函数的新环境和 package.loaded[name]
的新值,以便 require() 返回 t
。{name}
是一个复合名称(即一个由点分隔的组件名称),则 module
为每个组件创建(或如果已存在,则重用)表。例如,如果 {name}
是 a.b.c
,则 module
将模块表存储在全局 a
的 b
字段的 c
字段中。options
,其中每个选项都是要应用于模块的函数。{modname}
) require()package.loaded
表以确定 {modname}
是否已加载。如果是,则 require
返回存储在 package.loaded[modname]
中的值。否则,它将尝试为模块查找 loader
。require
首先查询 package.preload[modname]
。如果它具有值,则此值(应为函数)为加载器。否则,require
将使用存储在 package.path
中的路径搜索 Lua 加载器。如果这也失败,它将使用存储在 package.cpath
中的路径搜索 C 加载器。如果这也失败,它将尝试使用 all-in-one
加载器(见下文)。require
首先使用动态链接设施将应用程序与库链接。然后,它尝试在此库中查找一个用作加载器的 C 函数。此 C 函数的名称是字符串 "luaopen_"
与模块名称的副本(其中每个点都被下划线替换)连接而成。此外,如果模块名称包含连字符,则会删除其前缀(直到且包括第一个连字符)。例如,如果模块名称是 a.v1-b.c
,则函数名称将为 luaopen_b_c
。require
未为模块找到 Lua 库或 C 库,则它将调用 all-in-one
加载器。此加载器在 C 路径中搜索给定模块的根名称的库。例如,在需要 a.b.c
时,它将搜索 a
的 C 库。如果找到,它将在其中查找子模块的打开函数;在我们的示例中,这将是 luaopen_a_b_c
。通过此功能,一个包可以将多个 C 子模块打包到一个库中,每个子模块保留其原始的打开函数。require
将使用单个参数 {modname}
调用加载器。如果加载器返回任何值,require
将返回值分配给 package.loaded[modname]
。如果加载器未返回值并且未将任何值分配给 package.loaded[modname]
,则 require
将 true
分配给此条目。在任何情况下,require
都将返回 package.loaded[modname]
的最终值。require
将发出错误信号。package.path
相同的方式初始化 C 路径 package.cpath
,使用环境变量 LUA_CPATH
(以及在 luaconf.h
中定义的另一个默认路径)。require
用于控制哪些模块已加载的表。当您需要一个模块 modname
并且 package.loaded[modname]
不为假时,require
只会返回存储在那里的值。{libname}
, {funcname}
) package.loadlib(){libname}
动态链接。在此库中,查找函数 {funcname}
并将其作为 C 函数返回。(因此,{funcname}
必须遵循协议(参见 lua_CFunction)。require
不同,它不执行任何路径搜索,也不自动添加扩展名。{libname}
必须是 C 库的完整文件名,包括必要时路径和扩展名。{funcname}
必须是 C 库导出的确切名称(这可能取决于使用的 C 编译器和链接器)。dlfcn
标准的其他 Unix 系统)上可用。LUA_PATH
的值或在 luaconf.h
中定义的默认路径(如果环境变量未定义)初始化此变量。环境变量值中的任何 ";;"
都将被默认路径替换。templates
序列。对于每个模板,require
将使用 filename
(即 modname
,其中每个点都被替换为“目录分隔符”(如 Unix 中的 "/"
))将模板中的每个问号更改;然后它将尝试加载结果文件名。因此,例如,如果 Lua 路径是"./?.lua;./?.lc;/usr/local/?/init.lua"
foo
的 Lua 加载器将尝试加载文件 ./foo.lua
、./foo.lc
和 /usr/local/foo/init.lua
,按此顺序。{module}
) package.seeall(){module}
设置一个元表,其 __index
字段引用全局环境,以便此模块继承全局环境的值。用作函数 {module}
的选项。string
中提供所有函数。它还为字符串设置了一个元表,其中 __index
字段指向 string
表。因此,您可以以面向对象的方式使用字符串函数。例如,string.byte(s, i)
可以写成 s:byte(i)
。{s}
[, {i}
[, {j}
]]) string.byte()s[i]
、s[i+1]
、...、s[j]
的内部数值代码。{i}
的默认值为 1;{j}
的默认值为 {i}
。{function}
) string.dump(){function}
必须是一个没有上值的 Lua 函数。{s}
, {pattern}
[, {init}
[, {plain}
]]) string.find(){s}
中查找 {pattern}
的第一个匹配项。如果找到匹配项,则 {find}
将返回 {s}
中此匹配项开始和结束的索引;否则,它将返回 nil
。第三个可选的数值参数 {init}
指定开始搜索的位置;其默认值为 1,可以为负数。作为第四个可选参数的 {true}
值 {plain}
将关闭模式匹配功能,因此该函数执行简单的“查找子字符串”操作,{pattern}
中没有任何字符被视为“魔法”。请注意,如果给出 {plain}
,则也必须给出 {init}
。{formatstring}
, {...}
) string.format()printf
家族相同的规则。唯一的区别是,选项/修饰符 *
、l
、L
、n
、p
和 h
不受支持,并且还有一个额外的选项 q
。q
选项以适合安全读取回 Lua 解释器的形式格式化字符串:字符串写到双引号之间,并且字符串中的所有双引号、换行符、嵌入的零和反斜杠在写入时都会正确地转义。例如,调用string.format('%q', 'a string with "quotes" and \n new line')
"a string with \"quotes\" and \
new line"
c
、d
、E
、e
、f
、g
、G
、i
、o
、u
、X
和 x
都期望一个数字作为参数,而 q
和 s
期望一个字符串。{pattern}
没有指定捕获,则每次调用时都会生成整个匹配项。s = "hello world from Lua"
for w in string.gmatch(s, "%a+") do
print(w)
end
{s}
中的所有单词,每行打印一个单词。下一个示例将给定字符串中的所有 key=value
对收集到一个表中t = {}
s = "from=world, to=Lua"
for k, v in string.gmatch(s, "(%w+)=(%w+)") do
t[k] = v
end
{s}
, {pattern}
, {repl}
[, {n}
]) string.gsub(){s}
的副本,其中 {pattern}
的所有匹配项都被 {repl}
指定的替换字符串替换,{repl}
可以是字符串、表或函数。gsub
还将其第二个值作为返回值,即已进行的替换总数。{repl}
是一个字符串,则使用其值进行替换。字符 %
作为转义字符:{repl}
中任何形式为 %n
的序列,其中 {n}
在 1 到 9 之间,代表第 {n}
个捕获子字符串的值(见下文)。序列 %0
代表整个匹配项。序列 %%
代表单个 %
。{repl}
是一个表,则使用第一个捕获作为键,对每个匹配项查询该表;如果模式未指定任何捕获,则使用整个匹配项作为键。{repl}
是一个函数,则每次发生匹配时都会调用此函数,并将所有捕获的子字符串按顺序作为参数传递;如果模式未指定任何捕获,则将整个匹配项作为唯一参数传递。false
或 nil
,则不进行替换(即,字符串中的原始匹配项保留)。{n}
限制了发生替换的最大次数。例如,当 {n}
为 1 时,只替换 pattern
的第一个出现。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("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1")
--> x="world hello 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$", "%$(.-)%$", function (s)
return loadstring(s)()
end)
--> x="4+5 = 9"
local t = {name="lua", version="5.1"}
x = string.gsub("$name%-$version.tar.gz", "%$(%w+)", t)
--> x="lua-5.1.tar.gz"
{s}
, {pattern}
[, {init}
]) string.match(){s}
中查找 {pattern}
的第一个 match
。如果找到,则 match
返回模式中的捕获;否则返回 nil
。如果 {pattern}
未指定任何捕获,则返回整个匹配项。第三个可选的数字参数 {init}
指定搜索的起点;其默认值为 1,可以为负数。{s}
, {i}
[, {j}
]) string.sub(){s}
的子字符串,该子字符串从 {i}
开始,一直持续到 {j}
;{i}
和 {j}
可以为负数。如果 {j}
缺失,则假定它等于 -1
(与字符串长度相同)。特别是,调用 string.sub(s,1,j)
返回 {s}
的长度为 {j}
的前缀,而 string.sub(s,-i)
返回 {s}
的长度为 {i}
的后缀。x
(其中 x
不是魔法字符 ^$()%.[]*+-?
之一)代表字符 x
本身。.
(点)代表所有字符。%a
代表所有字母。%c
代表所有控制字符。%d
代表所有数字。%l
代表所有小写字母。%p
代表所有标点符号字符。%s
代表所有空格字符。%u
代表所有大写字母。%w
代表所有字母数字字符。%x
代表所有十六进制数字。%z
代表表示为 0
的字符。%x
(其中 x
是任何非字母数字字符)代表字符 x
。这是转义魔法字符的标准方法。任何标点符号字符(即使是非魔法字符)都可以在用作模式中的自身表示时,在其前面加上 %
。[set]
代表所有字符的并集,这些字符都在 set
中。可以通过使用 -
分隔范围的结束字符来指定字符范围。所有前面描述的类 %x
也可以用作 set
中的组件。set
中的所有其他字符都代表自身。例如,[%w_]
(或 [_%w]
)代表所有字母数字字符加上下划线,[0-7]
代表八进制数字,而 [0-7%l%-]
代表八进制数字加上小写字母加上 -
字符。[%a-z]
或 [a-%%]
这样的模式没有意义。[^set]
代表 set
的补集,其中 set
的解释如上所述。%a
、%c
等),相应的大写字母代表该类的补集。例如,%S
代表所有非空格字符。[a-z]
可能不等于 %l
。*
,匹配该类中 0 个或多个字符的重复。这些重复项将始终匹配最长的可能序列;+
,匹配该类中 1 个或多个字符的重复。这些重复项将始终匹配最长的可能序列;-
,也匹配该类中 0 个或多个字符的重复。与 *
不同,这些重复项将始终匹配最短的可能序列;?
,匹配该类中 0 个或 1 个字符的出现;%n
,对于 n
在 1 到 9 之间;此项匹配等于第 n
个捕获字符串的子字符串(见下文);%bxy
,其中 x
和 y
是两个不同的字符;此项匹配以 x
开头、以 y
结尾的字符串,并且 x
和 y
是平衡的。这意味着,如果从左到右读取字符串,对 x
计数 +1
,对 y
计数 -1
,则结尾的 y
是计数达到 0 的第一个 y
。例如,项 %b()
匹配具有平衡括号的表达式。^
将匹配锚定在主题字符串的开头。模式结尾的 $
将匹配锚定在主题字符串的结尾。在其他位置,^
和 $
没有特殊含义,代表自身。"(a*(.)%w(%s*))"
中,与 "a*(.)%w(%s*)"
匹配的字符串部分存储为第一个捕获(因此编号为 1);与 .
匹配的字符捕获编号为 2,与 %s*
匹配的部分编号为 3。()
捕获当前字符串位置(一个数字)。例如,如果我们在字符串 "flaaap"
上应用模式 "()aa()"
,将有两个捕获:3 和 5。%z
代替。table
中提供所有函数。{table}
[, {sep}
[, {i}
[, {j}
]]]) table.concat()table[i]..sep..table[i+1] ... sep..table[j]
。{sep}
的默认值为空字符串,{i}
的默认值为 1,{j}
的默认值为表的长度。如果 {i}
大于 {j}
,则返回空字符串。{table}
, {f}
) table.foreach(){table}
中的所有元素执行给定的 {f}
。对于每个元素,{f}
使用索引和相应的值作为参数被调用。如果 {f}
返回一个非 nil
值,则循环被中断,并且此值将作为 table.foreach
的最终值返回。{table}
, {f}
) table.foreachi(){table}
的数字索引执行给定的 {f}
。对于每个索引,{f}
使用索引和相应的值作为参数被调用。索引按顺序访问,从 1 到 n
,其中 n
是表的长度。如果 {f}
返回一个非 nil
值,则循环被中断,并且此值将作为 table.foreachi
的结果返回。{table}
, [{pos}
,] {value}
) table.insert(){table}
中的 {pos}
位置插入元素 {value}
,如有必要,将其他元素向上移动以腾出空间。{pos}
的默认值为 n+1
,其中 n
是表的长度(见 lua-length),因此调用 table.insert(t,x)
会在表 t
的末尾插入 x
。{table}
[, {pos}
]) table.remove(){table}
中删除 {pos}
位置的元素,如有必要,将其他元素向下移动以关闭空间。返回被删除元素的值。{pos}
的默认值为 n
,其中 n
是表的长度(见 lua-length),因此调用 table.remove(t)
会删除表 t
的最后一个元素。{table}
[, {comp}
]) table.sort()就地
排序,从 table[1]
到 table[n]
,其中 n
是表的长度(参见 lua-length)。如果给出了 {comp}
,则它必须是一个接收两个表元素并返回第一个元素小于第二个元素时为真的函数(这样在排序后 not comp(a[i+1],a[i])
为真)。如果没有给出 {comp}
,则使用标准 Lua 运算符 <
代替。不是
稳定的,也就是说,由给定顺序认为相等的元素可能在排序后改变其相对位置。math
中提供所有函数。[0,1)
范围内的伪随机实数。当带一个数字 {m}
调用时,math.random
返回 [1, m]
范围内的伪随机整数。当带两个数字 {m}
和 {n}
调用时,math.random
返回 [m, n]
范围内的伪随机整数。io
提供。当使用显式文件描述符时,操作 io.open
返回一个文件描述符,然后所有操作都作为文件描述符的方法提供。io
还提供三个预定义的文件描述符,其含义与 C 中的通常含义相同:io.stdin
、io.stdout
和 io.stderr
。nil
(以及错误消息作为第二个结果),并在成功时返回一些与 nil
不同的值。{file}
]) io.input()for line in io.lines(filename) do
body
end
nil
(以结束循环)并自动关闭文件。io.lines()
(不带文件名)等效于 io.input():lines()
;也就是说,它迭代默认输入文件中的行。在这种情况下,它在循环结束时不会关闭文件。{mode}
字符串可以是以下任何一种"r"
读模式(默认);"w"
写模式;"a"
追加模式;"r+"
更新模式,所有以前的数据都保留;"w+"
更新模式,所有以前的数据都将被擦除;"a+"
追加更新模式,保留以前的数据,写入仅允许在文件末尾进行。{mode}
字符串的末尾也可能有一个 b
,这在某些系统中是必要的,以便以二进制模式打开文件。此字符串与标准 C 函数 fopen
中使用的字符串完全相同。{prog}
[, {mode}
]) io.popen(){prog}
并返回一个文件句柄,您可以使用它从该程序读取数据(如果 {mode}
为 "r"
,则为默认值)或向该程序写入数据(如果 {mode}
为 "w"
)。{obj}
) io.type(){obj}
是否是一个有效的文件句柄。如果 {obj}
是一个打开的文件句柄,则返回字符串 "file"
,如果 {obj}
是一个关闭的文件句柄,则返回 "closed file"
,如果 {obj}
不是文件句柄,则返回 nil
。for line in file:lines() do
body
end
io.lines
不同,此函数在循环结束时不会关闭文件。){...}
) file:read()file
,这些格式指定要读取的内容。对于每个格式,函数返回一个包含读取字符的字符串(或数字),或者在无法按指定格式读取数据时返回 nil
。当不带格式调用时,它使用默认格式读取整个下一行(见下文)。"*n"
读取一个数字;这是唯一返回数字而不是字符串的格式。 "*a"
读取整个文件,从当前位置开始。在文件结束时,它返回空字符串。 "*l"
读取下一行(跳过行尾),在文件结束时返回 nil
。这是默认格式。 number
读取最多指定数量的字符的字符串,在文件结束时返回 nil
。如果 number 为零,则不读取任何内容并返回空字符串,或者在文件结束时返回 nil
。{whence}
] [, {offset}
]) file:seek(){offset}
加上由字符串 {whence}
指定的基准位置,如下所示"set"
: 基准为位置 0(文件开头);"cur"
: 基准为当前位置;"end"
: 基准为文件结尾;seek
返回最终文件位置,以从文件开头测量的字节为单位。如果此函数失败,它将返回 nil
,以及一个描述错误的字符串。{whence}
的默认值为 "cur"
,{offset}
的默认值为 0。因此,调用 file:seek()
返回当前文件位置,而不改变它;调用 file:seek("set")
将位置设置为文件开头(并返回 0);调用 file:seek("end")
将位置设置为文件结尾,并返回其大小。"no"
无缓冲;任何输出操作的结果都会立即出现。 "full"
全缓冲;输出操作仅在缓冲区已满时执行(或显式地 flush
文件时(参见 io.flush())。 "line"
行缓冲;输出被缓冲,直到输出一个换行符,或者有一些特殊文件(如终端设备)的输入。{size}
指定缓冲区的大小,以字节为单位。默认值为合适的大小。{...}
) file:write()file
。参数必须是字符串或数字。要写入其他值,请使用 tostring
tostring() 或 string.format
string.format() 在 write
之前。os
实现的。{format}
以 !
开头,则日期以协调世界时格式化。在这个可选字符之后,如果 {format}
是字符串 "*t"
,则 date
返回一个包含以下字段的表:year
(四位数字)、month
(1-12)、day
(1-31)、hour
(0-23)、min
(0-59)、sec
(0-61)、wday
(星期几,星期日为 1)、yday
(一年中的第几天)和 isdst
(夏令时标志,布尔值)。{format}
不是 "*t"
,则 date
返回日期作为字符串,根据与 C 函数 strftime
相同的规则格式化。date
返回一个合理的日期和时间表示,它取决于主机系统和当前区域设置(即,os.date()
等效于 os.date("%c")
)。{t2}
, {t1}
) os.difftime(){t1}
到时间 {t2}
的秒数。在 POSIX、Windows 和一些其他系统中,此值正好是 t2 - t1
。{command}
]) os.execute()system
。它将 {command}
传递给操作系统 shell 执行。它返回一个状态码,该状态码是系统相关的。如果 {command}
缺失,则如果 shell 可用,则返回非零值,否则返回零。{oldname}
, {newname}
) os.rename(){oldname}
的文件重命名为 {newname}
。如果此函数失败,它将返回 nil
,以及一个描述错误的字符串。{locale}
[, {category}
]) os.setlocale(){locale}
是一个指定区域设置的字符串;{category}
是一个可选的字符串,描述要更改的类别:"all"
、"collate"
、"ctype"
、"monetary"
、"numeric"
或 "time"
;默认类别为 "all"
。函数返回新区域设置的名称,或者如果请求无法满足,则返回 nil
。{table}
]) os.time()year
、month
和 day
,并且可能具有字段 hour
、min
、sec
和 isdst
(有关这些字段的描述,请参见 os.date
函数 os.date())。time
返回的数字只能用作 date
和 difftime
的参数。debug
表中提供。所有对线程进行操作的函数都有一个可选的第一个参数,即要操作的线程。默认值始终是当前线程。cont
的一行将完成此函数,以便调用者继续执行。debug.debug
的命令不会在任何函数中词法嵌套,因此无法直接访问局部变量。{thread}
]) debug.gethook()debug.sethook
函数设置)。{thread}
,] {function}
[, {what}
]) debug.getinfo(){function}
的值给出,这意味着在给定线程的调用栈的 {function}
级运行的函数:级别 0 是当前函数(getinfo
本身);级别 1 是调用 getinfo
的函数;等等。如果 {function}
是一个大于活动函数数量的数字,则 getinfo
返回 nil
。lua_getinfo
返回的所有字段(参见 lua_getinfo()),字符串 {what}
描述要填充的字段。{what}
的默认值为获取所有可用信息,除了有效行的表。如果存在,选项 f
将添加一个名为 func
的字段,其中包含函数本身。如果存在,选项 L
将添加一个名为 activelines
的字段,其中包含有效行的表。debug.getinfo(1,"n").name
返回当前函数的名称(如果可以找到合理的名称),并且 debug.getinfo(print)
返回一个包含有关 print
函数的所有可用信息的表。{thread}
,] {level}
, {local}
) debug.getlocal(){level}
层函数中索引为 {local}
的局部变量的名称和值。(第一个参数或局部变量的索引为 1,依此类推,直到最后一个活动的局部变量。) 如果没有给定索引的局部变量,则该函数返回 nil
,当使用超出范围的 {level}
调用时,该函数会引发错误。(您可以调用 debug.getinfo
debug.getinfo() 来检查级别是否有效。)(
(左括号)开头的变量名称代表内部变量(循环控制变量、临时变量和 C 函数局部变量)。{func}
, {up}
) debug.getupvalue(){func}
中索引为 {up}
的闭包变量的名称和值。如果不存在给定索引的闭包变量,该函数返回 nil
。{thread}
,] {hook}
, {mask}
[, {count}
]) debug.sethook(){mask}
和数字 {count}
描述了何时调用钩子。字符串掩码可以包含以下字符,具有以下含义"c"
: 每当 Lua 调用函数时,都会调用钩子;"r"
: 每当 Lua 从函数返回时,都会调用钩子;"l"
: 每当 Lua 进入新代码行时,都会调用钩子。{count}
非零时,在每 {count}
条指令后调用钩子。debug.sethook
会关闭钩子。"call"
、"return"
(或“tail return”)、"line"
和 "count"
。对于行事件,钩子也会得到新的行号作为其第二个参数。在钩子内部,您可以调用 getinfo
,级别为 2,以获取有关正在运行函数的更多信息(级别 0 是 getinfo
函数,级别 1 是钩子函数),除非事件是 "tail return"
。在这种情况下,Lua 只是模拟了返回,调用 getinfo
将返回无效数据。{thread}
,] {level}
, {local}
, {value}
) debug.setlocal(){value}
赋给堆栈第 {level}
层函数中索引为 {local}
的局部变量。如果不存在给定索引的局部变量,则该函数返回 nil
,当使用超出范围的 {level}
调用时,该函数会引发错误。(您可以调用 getinfo
来检查级别是否有效。) 否则,它将返回局部变量的名称。{func}
, {up}
, {value}
) debug.setupvalue(){value}
赋给函数 {func}
中索引为 {up}
的闭包变量。如果不存在给定索引的闭包变量,该函数返回 nil
。否则,它将返回闭包变量的名称。{thread}
,] [{message}
[,{level}
]]) debug.traceback(){message}
字符串将附加到回溯的开头。一个可选的 {level}
数字告诉从哪个级别开始回溯(默认值为 1,即调用 traceback
的函数)。