5.2 -
涉及协程的操作由基础库的一个子库组成,并且出现在表内。关于协程的全面描述见。
用f
主体创建一个新协程。f
必须是Lua函数。返回该新协程,它是类型为“thread
”的对象。
启动或继续协程co
的执行。首次恢复协程时,它启动运行协程主体。值val1
, ···是传入主体函数的参数。如果协程被中断了,resume
重新启动它;值val1
, ···是从yield传来的结果。
如果协程运行无误,resume
返回true以及传入yield
(如果协程中断)的任何值或由主体函数(如果协程结束)返回的任何值。如果有任何错误,resume
返回false以及错误消息。
返回运行的协程,或者当被主线程调用时返回nil。
返回协程co
的状态,以字符串的方式:如果协程正在运行(即是它调用了status
)则为“running
”;如果协程被yield
调用暂停或还未启动运行则为“suspended
”;如果协程是活动的但不在运行中(即它恢复了另一个协程)则为“normal
”;如果协程结束了它的主体函数或出错停止则为"dead"
。
用f
主体创建一个新协程。f
必须是Lua函数。返回一个函数,每次调用它会恢复协程。传入该函数的任何参数都作为resume
的额外参数。返回值同resume
相同,除了第一个布尔值。在发生错误情况下传播错误。
暂停调用者协程的执行。协程不能正在运行C函数、元方法或迭代器。yield
的任何参数被传为resume
的结果。
5.3 -
打包库为在Lua中加载和创建模块提供基础设备。它直接导出两个函数到全局环境中:和。其他东西都导出到表中。
创建一个模块。如果在package.loaded[name]
中有个表,该表就是模块。否则,如果有个给定名字的全局表t
,该表就是模块。否则创建新表t
并把它设为全局name
和package.loaded[name]
的值。该函数也用给定的名字初始化t._NAME
,用模块(t
自身)设置t._M
,并用包名设置t._PACKAGE
(完整模块名减去最后部分;见下)。最后,module
设置t
为当前函数的新环境和package.loaded[name]
的新值,因此返回t
。
如果name
是个复合名字(即用点号分隔的几个部分),module
为每个部分创建(或重用,如果它们已经存在)表。例如,如果name
是a.b.c
,则module
在全局a
的字段b
的字段c
中存储模块表。
该函数可以接受模块名后可选的options,其中每个选项是要加入模块的函数。
加载给定模块。该函数先浏览表确认modname
是否已经加载了。如果是,require
返回存储在package.loaded[modname]
中的值。否则,它尝试为模块找到一个加载器(loader)。
数组指示require
如何寻找加载器。通过改变该数组,我们可以改变require
如何寻找模块。下面的解释基于的缺省配置。
require
首先查询package.preload[modname]
。如果它有值,该值(应是个函数)就是加载器。否则require
使用存储在中的路径搜索一个Lua加载器。如果那也失败了,它用存储在中的路径搜索一个C加载器。如果也失败了,它尝试一个一体化(all-in-one)加载器(见)。
一旦找到,require
用单个参数modname
调用这个加载器。如果加载器返回任何值,require
把返回值赋给package.loaded[modname]
。如果加载器不返回值而且没有赋给package.loaded[modname]
任何值,require
把true赋给该条目。在任何情况下,require
返回package.loaded[modname]
的最终值。
如果加载或运行模块时发生任何错误,或者如果不能为模块找到任何加载器,require
导致一个错误。
该路径被用于搜索一个C加载器。
Lua用同初始化Lua路径一样的方式初始化C路径,利用环境变量或一个定义在luaconf.h
中的缺省路径。
被用来控制已经加载了哪些模块。当你require一个模块modname
而且package.loaded[modname]
不为假时,只是返回存储在那儿的值。
被用来控制如何加载模块的表。
该表的每个条目是个搜索器函数(searcher function)。当查找模块时,按照升序逐个调用这些搜索器,并用模块名(传给的参数)作为它的唯一参数。该函数可能返回另一个函数(模块加载器)或一条解释为何没找到模块的字符串(或nil,如果没话可说)。Lua用四个函数初始化该表。
第一个搜索器只是在表中查找加载器。
第二个搜索器(把模块)作为Lua库使用存储于中的路径查找加载器。路径是由分号分隔的一系列模板(template)。对每个模板,搜索器将模板中的每个问号改为filename
,后者是模块名,它的每个点号都被替换为“目录分隔符(directory separator)”(例如Unix中的/
);然后它将尝试打开合成的文件名。因此,例如,如果Lua路径是字符串
"./?.lua;./?.lc;/usr/local/?/init.lua"
对模块foo
的Lua文件的搜索将尝试按顺序打开文件./foo.lua
、./foo.lc
和/usr/local/foo/init.lua
。
第三个搜索器(把模块)作为C库用变量给出的路径查找加载器。例如,如果C路径是字符串
"./?.so;./?.dll;/usr/local/?/init.so"
对模块foo
的搜索将尝试按顺序打开文件./foo.so
、./foo.dll
和/usr/local/foo/init.so
。一旦找到C库,该搜索器首先用动态链接设备链接应用和库。然后尝试在库内查找一个将用作加载器的C函数。该C函数的名字是“luaopen_
”同模块名的拷贝连接得到的字符串,模块名的每个点号被下划线替换。此外,如果模块名有个连字符,它的直到(并且包括)第一个连字符的前缀被移除。例如,如果模块名是a.v1-b.c
,函数名将是luaopen_b_c
。
第四个搜索器尝试一个一体化加载器。它在C路径中为给定模块的根名搜索库。例如,当请求a.b.c
时,它将为a
搜索C库。如果找到了,在其中为子模块查找打开函数;在我们的例子中是luaopen_a_b_c
。利用该设备,包可以将若干C子模块打包在单个库中,其中的每个子模块持有自己的原始打开函数。
把C库libname
动态链接到宿主程序。在库内查找函数funcname
并作为C函数返回。(所以,funcname
必须遵循协议(见))。
这是个低级函数。它完全绕过包和模块系统。不像,它不执行任何陆路径搜索也不会自动地增加扩展名。libname
必须是C库的完全文见名,如果需要还包括路径和扩展名。funcname
必须是确切的C库导出的名字(依赖C编译器和链接器)。
该函数不被ANSI C支持。同样,它只在某些平台可用(Windows、Linux、Mac OS X、Solaris、BSD,以及支持dlfcn
标准的其他Unix系统)。
该路径被用来搜索一个Lua加载器。
Lua在启动时用环境变量的值初始化该变量,或者如果该环境变量未定义则用定义在luaconf.h
中的缺省路径。环境变量的值中的任何“;;
”都被替换为缺省路径。
用于特定模块存储加载器的表。(见)。
为module
设置元表,其__index
字段引用全局变量,所以该模块继承全局变量的值。将要被用作函数的一个选项。