Lua 5.3 å‚考手册
译者 云风
Lua.org, PUC-Rio ç‰ˆæƒæ‰€æœ‰ © 2015 , 在éµå¾ª Lua license æ¡æ¬¾ä¸‹ï¼Œå¯è‡ªç”±ä½¿ç”¨ã€‚
目录 · 索引 · ä¸è‹±æœ¯è¯å¯¹ç…§è¡¨
Lua 是一门扩展å¼ç¨‹åºè®¾è®¡è¯è¨€ï¼Œè¢«è®¾è®¡æˆæ”¯æŒé€šç”¨è¿‡ç¨‹å¼ç¼–ç¨‹ï¼Œå¹¶æœ‰ç›¸å…³æ•°æ®æè¿°è®¾æ–½ã€‚ åŒæ—¶å¯¹é¢å‘对象编程ã€å‡½æ•°å¼ç¼–程和数æ®é©±åЍå¼ç¼–程也æä¾›äº†è‰¯å¥½çš„æ”¯æŒã€‚ 它作为一个强大ã€è½»é‡çš„嵌入å¼è„šæœ¬è¯è¨€ï¼Œå¯ä¾›ä»»ä½•需è¦çš„程åºä½¿ç”¨ã€‚ Lua ç”± clean Cï¼ˆæ ‡å‡† C å’Œ C++ 间共通的å集) 实现æˆä¸€ä¸ªåº“。
作为一门扩展å¼è¯è¨€ï¼ŒLua 没有 "main" 程åºçš„æ¦‚念:
它åªèƒ½ 嵌入 一个宿主程åºä¸å·¥ä½œï¼Œ
该宿主程åºè¢«ç§°ä¸º è¢«åµŒå…¥ç¨‹åº æˆ–è€…ç®€ç§° 宿主 。
宿主程åºå¯ä»¥è°ƒç”¨å‡½æ•°æ‰§è¡Œä¸€å°æ®µ Lua 代ç ,å¯ä»¥è¯»å†™ Lua å˜é‡ï¼Œå¯ä»¥æ³¨å†Œ C 函数让 Lua 代ç 调用。
ä¾é C 函数,Lua å¯ä»¥å…±äº«ç›¸åŒçš„è¯æ³•框架æ¥å®šåˆ¶ç¼–程è¯è¨€ï¼Œä»Žè€Œé€‚用ä¸åŒçš„领域。
Lua 的官方å‘布版包å«ä¸€ä¸ªå«åš lua 的宿主程åºç¤ºä¾‹ï¼Œ
它是一个利用 Lua 库实现的完整独立的 Lua 解释器,å¯ç”¨äºŽäº¤äº’å¼åº”用或批处ç†ã€‚
Lua 是一个自由软件,其使用许å¯è¯å†³å®šäº†å®ƒçš„ä½¿ç”¨è¿‡ç¨‹æ— éœ€ä»»ä½•æ‹…ä¿ã€‚
本手册所æè¿°çš„实现å¯ä»¥åœ¨ Lua 的官方网站 www.lua.org 找到。
与其它的许多å‚è€ƒæ‰‹å†Œä¸€æ ·ï¼Œè¿™ä»½æ–‡æ¡£æœ‰äº›åœ°æ–¹æ¯”è¾ƒæž¯ç‡¥ã€‚ 关于 Lua 背åŽçš„è®¾è®¡æ€æƒ³ï¼Œ å¯ä»¥çœ‹çœ‹ Lua 网站上æä¾›çš„æŠ€æœ¯è®ºæ–‡ã€‚ 至于用 Lua 编程的细节介ç»ï¼Œ 请å‚阅 Roberto 的书,Programming in Lua。
æœ¬ç« æè¿°äº†è¯è¨€çš„基本概念。
Lua 是一门动æ€ç±»åž‹è¯è¨€ã€‚ è¿™æ„味ç€å˜é‡æ²¡æœ‰ç±»åž‹ï¼›åªæœ‰å€¼æ‰æœ‰ç±»åž‹ã€‚ è¯è¨€ä¸ä¸è®¾ç±»åž‹å®šä¹‰ã€‚ 所有的值æºå¸¦è‡ªå·±çš„类型。
Lua 䏿‰€æœ‰çš„值都是 一ç‰å…¬æ°‘。 è¿™æ„å‘³ç€æ‰€æœ‰çš„值å‡å¯ä¿å˜åœ¨å˜é‡ä¸ã€ å½“ä½œå‚æ•°ä¼ 递给其它函数ã€ä»¥åŠä½œä¸ºè¿”回值。
Lua 䏿œ‰å…«ç§åŸºæœ¬ç±»åž‹ï¼š
nilã€booleanã€numberã€stringã€functionã€userdataã€
thread 和 table。
Nil 是值 nil 的类型,
其主è¦ç‰¹å¾å°±æ˜¯å’Œå…¶å®ƒå€¼åŒºåˆ«å¼€ï¼›é€šå¸¸ç”¨æ¥è¡¨ç¤ºä¸€ä¸ªæœ‰æ„义的值ä¸å˜åœ¨æ—¶çš„状æ€ã€‚
Boolean 是 false 与 true 两个值的类型。
nil å’Œ false 都会导致æ¡ä»¶åˆ¤æ–为å‡ï¼›
而其它任何值都表示为真。
Number 代表了整数和实数(浮点数)。
String 表示一个ä¸å¯å˜çš„å—节åºåˆ—。
Lua 对 8 使˜¯å‹å¥½çš„:
å—符串å¯ä»¥å®¹çº³ä»»æ„ 8 ä½å€¼ï¼Œ
å…¶ä¸åŒ…å«é›¶ ('\0') 。
Lua çš„å—ç¬¦ä¸²ä¸Žç¼–ç æ— 关;
它ä¸å…³å¿ƒå—符串ä¸å…·ä½“内容。
number 类型有两ç§å†…部表现方å¼ï¼Œ
整数 和 浮点数。
对于何时使用哪ç§å†…部形å¼ï¼ŒLua 有明确的规则,
但它也按需(å‚è§ §3.4.3)作自动转æ¢ã€‚
å› æ¤ï¼Œç¨‹åºå‘˜å¤šæ•°æƒ…况下å¯ä»¥é€‰æ‹©å¿½ç•¥æ•´æ•°ä¸Žæµ®ç‚¹æ•°ä¹‹é—´çš„差异或者å‡è®¾å®Œå…¨æŽ§åˆ¶æ¯ä¸ªæ•°å—的内部表现方å¼ã€‚
æ ‡å‡† Lua 使用 64 使•´æ•°å’ŒåŒç²¾åº¦ï¼ˆ64 ä½ï¼‰æµ®ç‚¹æ•°ï¼Œ
ä½†ä½ ä¹Ÿå¯ä»¥æŠŠ Lua 编译æˆä½¿ç”¨ 32 使•´æ•°å’Œå•精度(32 ä½ï¼‰æµ®ç‚¹æ•°ã€‚
以 32 ä½è¡¨ç¤ºæ•°å—对å°åž‹æœºå™¨ä»¥åŠåµŒå…¥å¼ç³»ç»Ÿç‰¹åˆ«åˆé€‚。
(å‚è§ luaconf.h 文件ä¸çš„å® LUA_32BITS 。)
Lua å¯ä»¥è°ƒç”¨ï¼ˆä»¥åŠæ“作)用 Lua 或 C (å‚è§ §3.4.10)编写的函数。 这两ç§å‡½æ•°æœ‰ç»Ÿä¸€ç±»åž‹ function。
userdata 类型å…许将 C ä¸çš„æ•°æ®ä¿å˜åœ¨ Lua å˜é‡ä¸ã€‚ 用户数æ®ç±»åž‹çš„值是一个内å˜å—, 有两ç§ç”¨æˆ·æ•°æ®ï¼š å®Œå…¨ç”¨æˆ·æ•°æ® ï¼ŒæŒ‡ä¸€å—ç”± Lua 管ç†çš„内å˜å¯¹åº”的对象; è½»é‡ç”¨æˆ·æ•°æ® ,则指一个简å•çš„ C 指针。 用户数æ®åœ¨ Lua ä¸é™¤äº†èµ‹å€¼ä¸Žç›¸ç‰æ€§åˆ¤æ–之外没有其他预定义的æ“作。 通过使用 元表 ,程åºå‘˜å¯ä»¥ç»™å®Œå…¨ç”¨æˆ·æ•°æ®å®šä¹‰ä¸€ç³»åˆ—çš„æ“作 (å‚è§ §2.4)。 ä½ åªèƒ½é€šè¿‡ C API è€Œæ— æ³•åœ¨ Lua 代ç ä¸åˆ›å»ºæˆ–者修改用户数æ®çš„值, è¿™ä¿è¯äº†æ•°æ®ä»…è¢«å®¿ä¸»ç¨‹åºæ‰€æŽ§åˆ¶ã€‚
thread 类型表示了一个独立的执行åºåˆ—,被用于实现å程 (å‚è§ §2.6)。 Lua 的线程与æ“ä½œç³»ç»Ÿçš„çº¿ç¨‹æ¯«æ— å…³ç³»ã€‚ Lua ä¸ºæ‰€æœ‰çš„ç³»ç»Ÿï¼ŒåŒ…æ‹¬é‚£äº›ä¸æ”¯æŒåŽŸç”Ÿçº¿ç¨‹çš„ç³»ç»Ÿï¼Œæä¾›äº†å程支æŒã€‚
table æ˜¯ä¸€ä¸ªå…³è”æ•°ç»„,
也就是说,这个数组ä¸ä»…仅以数å—åšç´¢å¼•,除了 nil å’Œ NaN 之外的所有 Lua 值
都å¯ä»¥åšç´¢å¼•。
(Not a Number 是一个特殊的数å—,它用于表示未定义或表示ä¸äº†çš„è¿ç®—结果,比如 0/0。)
表å¯ä»¥æ˜¯ 异构 的;
也就是说,表内å¯ä»¥åŒ…å«ä»»ä½•类型的值( nil 除外)。
任何键的值若为 nil å°±ä¸ä¼šè¢«è®°å…¥è¡¨ç»“构内部。
æ¢è¨€ä¹‹ï¼Œå¯¹äºŽè¡¨å†…ä¸å˜åœ¨çš„键,都对应ç€å€¼ nil 。
表是 Lua ä¸å”¯ä¸€çš„æ•°æ®ç»“构,
它å¯è¢«ç”¨äºŽè¡¨ç¤ºæ™®é€šæ•°ç»„ã€åºåˆ—ã€ç¬¦å·è¡¨ã€é›†åˆã€è®°å½•ã€å›¾ã€æ ‘ç‰ç‰ã€‚
对于记录,Lua 使用域å作为索引。
è¯è¨€æä¾›äº† a.name è¿™æ ·çš„è¯æ³•ç³–æ¥æ›¿ä»£
a["name"] è¿™ç§å†™æ³•以方便记录这ç§ç»“构的使用。
在 Lua 䏿œ‰å¤šç§ä¾¿åˆ©çš„æ–¹å¼åˆ›å»ºè¡¨ï¼ˆå‚è§ §3.4.9)。
我们使用 åºåˆ— è¿™ä¸ªæœ¯è¯æ¥è¡¨ç¤ºä¸€ä¸ªç”¨ {1..n} çš„æ£æ•´æ•°é›†åšç´¢å¼•的表。 这里的éžè´Ÿæ•´æ•° n 被称为该åºåˆ—的长度(å‚è§ §3.4.7)。
å’Œç´¢å¼•ä¸€æ ·ï¼Œè¡¨ä¸æ¯ä¸ªåŸŸçš„值也å¯ä»¥æ˜¯ä»»ä½•类型。 需è¦ç‰¹åˆ«æŒ‡å‡ºçš„æ˜¯ï¼šæ—¢ç„¶å‡½æ•°æ˜¯ä¸€ç‰å…¬æ°‘,那么表的域也å¯ä»¥æ˜¯å‡½æ•°ã€‚ è¿™æ ·ï¼Œè¡¨å°±å¯ä»¥æºå¸¦ 方法 了。 (å‚è§ §3.4.11)。
ç´¢å¼•ä¸€å¼ è¡¨çš„åŽŸåˆ™éµå¾ªè¯è¨€ä¸çš„直接比较规则。
当且仅当 i 与 jç›´æŽ¥æ¯”è¾ƒç›¸ç‰æ—¶
(å³ä¸é€šè¿‡å…ƒæ–¹æ³•的比较),
è¡¨è¾¾å¼ a[i] 与 a[j]
表示了表ä¸ç›¸åŒçš„å…ƒç´ ã€‚
特别指出:一个å¯ä»¥å®Œå…¨è¡¨ç¤ºä¸ºæ•´æ•°çš„æµ®ç‚¹æ•°å’Œå¯¹åº”的整数相ç‰
(例如:1.0 == 1)。
为了消除æ§ä¹‰ï¼Œå½“一个å¯ä»¥å®Œå…¨è¡¨ç¤ºä¸ºæ•´æ•°çš„æµ®ç‚¹æ•°åšä¸ºé”®å€¼æ—¶ï¼Œ
都会被转æ¢ä¸ºå¯¹åº”的整数储å˜ã€‚
ä¾‹å¦‚ï¼Œå½“ä½ å†™ a[2.0] = true 时,
实际被æ’入表ä¸çš„键是整数 2 。
(å¦ä¸€æ–¹é¢ï¼Œ2 与 "2" 是两个ä¸åŒçš„ Lua 值,
故而它们å¯ä»¥æ˜¯åŒä¸€å¼ 表ä¸çš„ä¸åŒé¡¹ã€‚)
表ã€å‡½æ•°ã€çº¿ç¨‹ã€ä»¥åŠå®Œå…¨ç”¨æˆ·æ•°æ®åœ¨ Lua ä¸è¢«ç§°ä¸º 对象: å˜é‡å¹¶ä¸çœŸçš„ æŒæœ‰ 它们的值,而仅ä¿å˜äº†å¯¹è¿™äº›å¯¹è±¡çš„ 引用。 赋值ã€å‚æ•°ä¼ é€’ã€å‡½æ•°è¿”å›žï¼Œéƒ½æ˜¯é’ˆå¯¹å¼•ç”¨è€Œä¸æ˜¯é’ˆå¯¹å€¼çš„æ“ä½œï¼Œ 这些æ“作å‡ä¸ä¼šåšä»»ä½•å½¢å¼çš„éšå¼æ‹·è´ã€‚
库函数 type 用于以å—符串形å¼è¿”回给定值的类型。
(å‚è§ §6.1)。
åŽé¢åœ¨ §3.2 ä»¥åŠ §3.3.3 会讨论,
å¼•ç”¨ä¸€ä¸ªå« var 的自由åå—(指在任何层级都未被声明的åå—)
åœ¨å¥æ³•上都被翻译为 _ENV.var 。
æ¤å¤–,æ¯ä¸ªè¢«ç¼–译的 Lua 代ç å—都会有一个外部的局部å˜é‡å« _ENV
(å‚è§ §3.3.2),
å› æ¤ï¼Œ_ENV 这个åå—æ°¸è¿œéƒ½ä¸ä¼šæˆä¸ºä¸€ä¸ªä»£ç å—ä¸çš„自由åå—。
在转译那些自由åå—æ—¶ï¼Œ_ENV æ˜¯å¦æ˜¯é‚£ä¸ªå¤–部的局部å˜é‡æ— 所谓。
_ENV å’Œå…¶å®ƒä½ å¯ä»¥ä½¿ç”¨çš„å˜é‡å没有区别。
è¿™é‡Œç‰¹åˆ«æŒ‡å‡ºï¼Œä½ å¯ä»¥å®šä¹‰ä¸€ä¸ªæ–°å˜é‡æˆ–æŒ‡å®šä¸€ä¸ªå‚æ•°å«è¿™ä¸ªåå—。
当编译器在转译自由åå—æ—¶æ‰€ç”¨åˆ°çš„ _ENV ,
æŒ‡çš„æ˜¯ä½ çš„ç¨‹åºåœ¨é‚£ä¸ªç‚¹ä¸Šå¯è§çš„那个å为 _ENV çš„å˜é‡ã€‚
(Lua çš„å¯è§æ€§è§„则å‚è§ §3.5)
被 _ENV ç”¨äºŽå€¼çš„é‚£å¼ è¡¨è¢«ç§°ä¸º 环境。
Lua ä¿æœ‰ä¸€ä¸ªè¢«ç§°ä¸º 全局环境 特别环境。它被ä¿å˜åœ¨ C 注册表
(å‚è§ §4.5)的一个特别索引下。
在 Lua ä¸ï¼Œå…¨å±€å˜é‡ _G 被åˆå§‹åŒ–为这个值。
(_G ä¸è¢«å†…部任何地方使用。)
当 Lua åŠ è½½ä¸€ä¸ªä»£ç å—,_ENV 这个上值的默认值就是这个全局环境
(å‚è§ load)。
å› æ¤ï¼Œåœ¨é»˜è®¤æƒ…况下,Lua 代ç 䏿åŠçš„自由åå—都指的全局环境ä¸çš„相关项
ï¼ˆå› æ¤ï¼Œå®ƒä»¬ä¹Ÿè¢«ç§°ä¸º 全局å˜é‡ )。
æ¤å¤–ï¼Œæ‰€æœ‰çš„æ ‡å‡†åº“éƒ½è¢«åŠ è½½å…¥å…¨å±€çŽ¯å¢ƒï¼Œä¸€äº›å‡½æ•°ä¹Ÿé’ˆå¯¹è¿™ä¸ªçŽ¯å¢ƒåšæ“作。
ä½ å¯ä»¥ç”¨ load (或 loadfileï¼‰åŠ è½½ä»£ç å—,并赋予它们ä¸åŒçš„环境。
(在 C é‡Œï¼Œå½“ä½ åŠ è½½ä¸€ä¸ªä»£ç å—åŽï¼Œå¯ä»¥é€šè¿‡æ”¹å˜å®ƒçš„ç¬¬ä¸€ä¸ªä¸Šå€¼æ¥æ”¹å˜å®ƒçš„环境。)
由于 Lua æ˜¯ä¸€é—¨åµŒå…¥å¼æ‰©å±•è¯è¨€ï¼Œå…¶æ‰€æœ‰è¡Œä¸ºå‡æºäºŽå®¿ä¸»ç¨‹åºä¸ C 代ç 对æŸä¸ª Lua 库函数的调用。
(å•独使用 Lua 时,lua 程åºå°±æ˜¯å®¿ä¸»ç¨‹åºã€‚)
所以,在编译或è¿è¡Œ Lua 代ç å—的过程ä¸ï¼Œæ— 论何时å‘生错误,
控制æƒéƒ½è¿”å›žç»™å®¿ä¸»ï¼Œç”±å®¿ä¸»è´Ÿè´£é‡‡å–æ°å½“的措施(比如打å°é”™è¯¯æ¶ˆæ¯ï¼‰ã€‚
å¯ä»¥åœ¨ Lua 代ç ä¸è°ƒç”¨ error å‡½æ•°æ¥æ˜¾å¼åœ°æŠ›å‡ºä¸€ä¸ªé”™è¯¯ã€‚
å¦‚æžœä½ éœ€è¦åœ¨ Lua 䏿•获这些错误,
å¯ä»¥ä½¿ç”¨ pcall 或
xpcall
在 ä¿æŠ¤æ¨¡å¼ ä¸‹è°ƒç”¨ä¸€ä¸ªå‡½æ•°ã€‚
æ— è®ºä½•æ—¶å‡ºçŽ°é”™è¯¯ï¼Œéƒ½ä¼šæŠ›å‡ºä¸€ä¸ªæºå¸¦é”™è¯¯ä¿¡æ¯çš„ 错误对象 (错误消æ¯ï¼‰ã€‚ Lua 本身åªä¼šä¸ºé”™è¯¯ç”Ÿæˆå—符串类型的错误对象, ä½†ä½ çš„ç¨‹åºå¯ä»¥ä¸ºé”™è¯¯ç”Ÿæˆä»»ä½•类型的错误对象, è¿™å°±çœ‹ä½ çš„ Lua ç¨‹åºæˆ–宿主程åºå¦‚何处ç†è¿™äº›é”™è¯¯å¯¹è±¡ã€‚
使用 xpcall 或
lua_pcall 时,
ä½ åº”è¯¥æä¾›ä¸€ä¸ª 消æ¯å¤„ç†å‡½æ•° 用于错误抛出时调用。
该函数需接收原始的错误消æ¯ï¼Œå¹¶è¿”回一个新的错误消æ¯ã€‚
它在错误å‘ç”ŸåŽæ ˆå°šæœªå±•开时调用,
å› æ¤å¯ä»¥åˆ©ç”¨æ ˆæ¥æ”¶é›†æ›´å¤šçš„ä¿¡æ¯ï¼Œ
æ¯”å¦‚é€šè¿‡æŽ¢çŸ¥æ ˆæ¥åˆ›å»ºä¸€ç»„æ ˆå›žæº¯ä¿¡æ¯ã€‚
åŒæ—¶ï¼Œè¯¥å¤„ç†å‡½æ•°ä¹Ÿå¤„äºŽä¿æŠ¤æ¨¡å¼ä¸‹ï¼Œæ‰€ä»¥è¯¥å‡½æ•°å†…å‘ç”Ÿçš„é”™è¯¯ä¼šå†æ¬¡è§¦å‘它(递归)。
如果递归太深,Lua 会终æ¢è°ƒç”¨å¹¶è¿”回一个åˆé€‚的消æ¯ã€‚
Lua ä¸çš„æ¯ä¸ªå€¼éƒ½å¯ä»¥æœ‰ä¸€ä¸ª 元表。
这个 元表 就是一个普通的 Lua 表,
它用于定义原始值在特定æ“作下的行为。
å¦‚æžœä½ æƒ³æ”¹å˜ä¸€ä¸ªå€¼åœ¨ç‰¹å®šæ“ä½œä¸‹çš„è¡Œä¸ºï¼Œä½ å¯ä»¥åœ¨å®ƒçš„元表ä¸è®¾ç½®å¯¹åº”域。
ä¾‹å¦‚ï¼Œå½“ä½ å¯¹éžæ•°å—值åšåŠ æ“作时,
Lua 会检查该值的元表ä¸çš„ "__add" 域下的函数。
如果能找到,Lua 则调用这个函数æ¥å®ŒæˆåŠ è¿™ä¸ªæ“作。
在元表ä¸äº‹ä»¶çš„键值是一个åŒä¸‹åˆ’线(__ï¼‰åŠ äº‹ä»¶åçš„å—符串;
键关è”的那些值被称为 元方法。
在上一个例åä¸ï¼Œ__add 就是键值,
å¯¹åº”çš„å…ƒæ–¹æ³•æ˜¯æ‰§è¡ŒåŠ æ“作的函数。
ä½ å¯ä»¥ç”¨ getmetatable 函数
æ¥èŽ·å–任何值的元表。
Lua 使用直接访问的方å¼ä»Žå…ƒè¡¨ä¸æŸ¥è¯¢å…ƒæ–¹æ³•(å‚è§rawget)。
所以,从对象 o ä¸èŽ·å–事件 ev 的元方法ç‰ä»·äºŽä¸‹é¢çš„代ç :
rawget(getmetatable(o) or {}, "__ev")
ä½ å¯ä»¥ä½¿ç”¨ setmetatable
æ¥æ›¿æ¢ä¸€å¼ 表的元表。在 Lua ä¸ï¼Œä½ ä¸å¯ä»¥æ”¹å˜è¡¨ä»¥å¤–其它类型的值的元表
(除éžä½ 使用调试库(å‚è§§6.10));
若想改å˜è¿™äº›éžè¡¨ç±»åž‹çš„值的元表,请使用 C API。
è¡¨å’Œå®Œå…¨ç”¨æˆ·æ•°æ®æœ‰ç‹¬ç«‹çš„元表 (当然,多个表和用户数æ®å¯ä»¥å…±äº«åŒä¸€ä¸ªå…ƒè¡¨ï¼‰ã€‚ 其它类型的值按类型共享元表; 也就是说所有的数å—都共享åŒä¸€ä¸ªå…ƒè¡¨ï¼Œ 所有的å—符串共享å¦ä¸€ä¸ªå…ƒè¡¨ç‰ç‰ã€‚ 默认情况下,值是没有元表的, 但å—符串库在åˆå§‹åŒ–的时候为å—符串类型设置了元表 (å‚è§ §6.4)。
元表决定了一个对象在数å¦è¿ç®—ã€ä½è¿ç®—ã€æ¯”较ã€è¿žæŽ¥ã€ å–长度ã€è°ƒç”¨ã€ç´¢å¼•时的行为。 元表还å¯ä»¥å®šä¹‰ä¸€ä¸ªå‡½æ•°ï¼Œå½“表对象或用户数æ®å¯¹è±¡åœ¨åžƒåœ¾å›žæ”¶ (å‚è§§2.5)时调用它。
对于一元æ“作符(å–è´Ÿã€æ±‚长度ã€ä½å), å…ƒæ–¹æ³•è°ƒç”¨çš„æ—¶å€™ï¼Œç¬¬äºŒä¸ªå‚æ•°æ˜¯ä¸ªå“‘元,其值ç‰äºŽç¬¬ä¸€ä¸ªå‚数。 è¿™æ ·å¤„ç†ä»…仅是为了简化 Lua 的内部实现 ï¼ˆè¿™æ ·å¤„ç†å¯ä»¥è®©æ‰€æœ‰çš„æ“ä½œéƒ½å’ŒäºŒå…ƒæ“作一致), 这个行为有å¯èƒ½åœ¨å°†æ¥çš„版本ä¸ç§»é™¤ã€‚ (使用这个é¢å¤–傿•°çš„行为都是ä¸ç¡®å®šçš„。)
æŽ¥ä¸‹æ¥æ˜¯å…ƒè¡¨å¯ä»¥æŽ§åˆ¶çš„事件的详细列表。
æ¯ä¸ªæ“ä½œéƒ½ç”¨å¯¹åº”çš„äº‹ä»¶åæ¥åŒºåˆ†ã€‚
æ¯ä¸ªäº‹ä»¶çš„é”®åç”¨åŠ æœ‰ '__' å‰ç¼€çš„å—符串æ¥è¡¨ç¤ºï¼›
例如 "add" æ“作的键å为å—符串 "__add"。
__add:
+ æ“作。
å¦‚æžœä»»ä½•ä¸æ˜¯æ•°å—的值(包括ä¸èƒ½è½¬æ¢ä¸ºæ•°å—çš„å—符串)åšåŠ æ³•ï¼Œ
Lua 就会å°è¯•调用元方法。
首先ã€Lua 检查第一个æ“作数(å³ä½¿å®ƒæ˜¯åˆæ³•的),
如果这个æ“作数没有为 "__add" 事件定义元方法,
Lua å°±ä¼šæŽ¥ç€æ£€æŸ¥ç¬¬äºŒä¸ªæ“作数。
一旦 Lua 找到了元方法,
它将把两个æ“ä½œæ•°ä½œä¸ºå‚æ•°ä¼ 入元方法,
元方法的结果(调整为å•个值)作为这个æ“作的结果。
如果找ä¸åˆ°å…ƒæ–¹æ³•,将抛出一个错误。
__sub:
- æ“作。
行为和 "add" æ“作类似。
__mul:
* æ“作。
行为和 "add" æ“作类似。
__div:
/ æ“作。
行为和 "add" æ“作类似。
__mod:
% æ“作。
行为和 "add" æ“作类似。
__pow:
^ (次方)æ“作。
行为和 "add" æ“作类似。
__unm:
- (å–负)æ“作。
行为和 "add" æ“作类似。
__idiv:
// (å‘䏋喿•´é™¤æ³•)æ“作。
行为和 "add" æ“作类似。
__band:
& (按ä½ä¸Žï¼‰æ“作。
行为和 "add" æ“作类似,
ä¸åŒçš„æ˜¯ Lua 会在任何一个æ“ä½œæ•°æ— æ³•è½¬æ¢ä¸ºæ•´æ•°æ—¶
(å‚è§ §3.4.3)å°è¯•å–元方法。
__bor:
| ï¼ˆæŒ‰ä½æˆ–)æ“作。
行为和 "band" æ“作类似。
__bxor:
~ (按ä½å¼‚或)æ“作。
行为和 "band" æ“作类似。
__bnot:
~ (按ä½éžï¼‰æ“作。
行为和 "band" æ“作类似。
__shl:
<< (左移)æ“作。
行为和 "band" æ“作类似。
__shr:
>> (å³ç§»ï¼‰æ“作。
行为和 "band" æ“作类似。
__concat:
.. (连接)æ“作。
行为和 "add" æ“作类似,
ä¸åŒçš„æ˜¯ Lua 在任何æ“作数å³ä¸æ˜¯ä¸€ä¸ªå—符串
ä¹Ÿä¸æ˜¯æ•°å—ï¼ˆæ•°å—æ€»èƒ½è½¬æ¢ä¸ºå¯¹åº”çš„å—符串)的情况下å°è¯•元方法。
__len:
# (å–长度)æ“作。
å¦‚æžœå¯¹è±¡ä¸æ˜¯å—符串,Lua 会å°è¯•它的元方法。
å¦‚æžœæœ‰å…ƒæ–¹æ³•ï¼Œåˆ™è°ƒç”¨å®ƒå¹¶å°†å¯¹è±¡ä»¥å‚æ•°å½¢å¼ä¼ 入,
而返回值(被调整为å•个)则作为结果。
å¦‚æžœå¯¹è±¡æ˜¯ä¸€å¼ è¡¨ä¸”æ²¡æœ‰å…ƒæ–¹æ³•ï¼Œ
Lua 使用表的å–长度æ“作(å‚è§ §3.4.7)。
å…¶å®ƒæƒ…å†µï¼Œå‡æŠ›å‡ºé”™è¯¯ã€‚
__eq:
== (ç‰äºŽï¼‰æ“作。
å’Œ "add" æ“作行为类似,
ä¸åŒçš„æ˜¯ Lua 仅在两个值都是表或都是完全用户数æ®
ä¸”å®ƒä»¬ä¸æ˜¯åŒä¸€ä¸ªå¯¹è±¡æ—¶æ‰å°è¯•元方法。
调用的结果总会被转æ¢ä¸ºå¸ƒå°”é‡ã€‚
__lt:
< (å°äºŽï¼‰æ“作。
å’Œ "add" æ“作行为类似,
ä¸åŒçš„æ˜¯ Lua 仅在两个值ä¸å…¨ä¸ºæ•´æ•°ä¹Ÿä¸å…¨ä¸ºå—符串时æ‰å°è¯•元方法。
调用的结果总会被转æ¢ä¸ºå¸ƒå°”é‡ã€‚
__le:
<= (å°äºŽç‰äºŽï¼‰æ“作。
和其它æ“作ä¸åŒï¼Œ
å°äºŽç‰äºŽæ“作å¯èƒ½ç”¨åˆ°ä¸¤ä¸ªä¸åŒçš„事件。
é¦–å…ˆï¼Œåƒ "lt" æ“ä½œçš„è¡Œä¸ºé‚£æ ·ï¼ŒLua 在两个æ“ä½œæ•°ä¸æŸ¥æ‰¾ "__le" 元方法。
如果一个元方法都找ä¸åˆ°ï¼Œå°±ä¼šå†æ¬¡æŸ¥æ‰¾ "__lt" 事件,
它会å‡è®¾ a <= b ç‰ä»·äºŽ not (b < a)。
而其它比较æ“作符类似,其结果会被转æ¢ä¸ºå¸ƒå°”é‡ã€‚
__index:
索引 table[key]。
当 table 䏿˜¯è¡¨æˆ–是表 table ä¸ä¸å˜åœ¨
key 这个键时,这个事件被触å‘。
æ¤æ—¶ï¼Œä¼šè¯»å‡º table 相应的元方法。
尽管åå—å–æˆè¿™æ ·ï¼Œ
这个事件的元方法其实å¯ä»¥æ˜¯ä¸€ä¸ªå‡½æ•°ä¹Ÿå¯ä»¥æ˜¯ä¸€å¼ 表。
如果它是一个函数,则以 table å’Œ key ä½œä¸ºå‚æ•°è°ƒç”¨å®ƒã€‚
å¦‚æžœå®ƒæ˜¯ä¸€å¼ è¡¨ï¼Œæœ€ç»ˆçš„ç»“æžœå°±æ˜¯ä»¥ key å–ç´¢å¼•è¿™å¼ è¡¨çš„ç»“æžœã€‚
(这个索引过程是走常规的æµç¨‹ï¼Œè€Œä¸æ˜¯ç›´æŽ¥ç´¢å¼•,
所以这次索引有å¯èƒ½å¼•å‘å¦ä¸€æ¬¡å…ƒæ–¹æ³•。)
__newindex:
索引赋值 table[key] = value 。
和索引事件类似,它å‘生在
table 䏿˜¯è¡¨æˆ–是表 table ä¸ä¸å˜åœ¨
key 这个键的时候。
æ¤æ—¶ï¼Œä¼šè¯»å‡º table 相应的元方法。
åŒç´¢å¼•è¿‡ç¨‹é‚£æ ·ï¼Œ
这个事件的元方法å³å¯ä»¥æ˜¯å‡½æ•°ï¼Œä¹Ÿå¯ä»¥æ˜¯ä¸€å¼ 表。
如果是一个函数,
则以 table〠keyã€ä»¥åŠ value ä¸ºå‚æ•°ä¼ 入。
å¦‚æžœæ˜¯ä¸€å¼ è¡¨ï¼Œ
Lua å¯¹è¿™å¼ è¡¨åšç´¢å¼•赋值æ“作。
(这个索引过程是走常规的æµç¨‹ï¼Œè€Œä¸æ˜¯ç›´æŽ¥ç´¢å¼•赋值,
所以这次索引赋值有å¯èƒ½å¼•å‘å¦ä¸€æ¬¡å…ƒæ–¹æ³•。)
一旦有了 "newindex" 元方法,
Lua å°±ä¸å†åšæœ€åˆçš„赋值æ“作。
(如果有必è¦ï¼Œåœ¨å…ƒæ–¹æ³•内部å¯ä»¥è°ƒç”¨ rawset
æ¥åšèµ‹å€¼ã€‚)
__call:
函数调用æ“作 func(args)。
当 Lua å°è¯•调用一个éžå‡½æ•°çš„值的时候会触å‘这个事件
ï¼ˆå³ func 䏿˜¯ä¸€ä¸ªå‡½æ•°ï¼‰ã€‚
查找 func 的元方法,
如果找得到,就调用这个元方法,
func ä½œä¸ºç¬¬ä¸€ä¸ªå‚æ•°ä¼ 入,原æ¥è°ƒç”¨çš„傿•°ï¼ˆargs)åŽä¾æ¬¡æŽ’在åŽé¢ã€‚
Lua 采用了自动内å˜ç®¡ç†ã€‚ è¿™æ„味ç€ä½ ä¸ç”¨æ“心新创建的对象需è¦çš„内å˜å¦‚何分é…出æ¥ï¼Œ 也ä¸ç”¨è€ƒè™‘在对象ä¸å†è¢«ä½¿ç”¨åŽæ€Žæ ·é‡Šæ”¾å®ƒä»¬æ‰€å 用的内å˜ã€‚ Lua è¿è¡Œäº†ä¸€ä¸ª 垃圾收集器 æ¥æ”¶é›†æ‰€æœ‰ æ»å¯¹è±¡ (å³åœ¨ Lua ä¸ä¸å¯èƒ½å†è®¿é—®åˆ°çš„对象)æ¥å®Œæˆè‡ªåЍ内å˜ç®¡ç†çš„工作。 Lua 䏿‰€æœ‰ç”¨åˆ°çš„内å˜ï¼Œå¦‚:å—符串ã€è¡¨ã€ç”¨æˆ·æ•°æ®ã€å‡½æ•°ã€çº¿ç¨‹ã€ 内部结构ç‰ï¼Œéƒ½æœä»Žè‡ªåŠ¨ç®¡ç†ã€‚
Lua å®žçŽ°äº†ä¸€ä¸ªå¢žé‡æ ‡è®°-æ‰«ææ”¶é›†å™¨ã€‚ å®ƒä½¿ç”¨è¿™ä¸¤ä¸ªæ•°å—æ¥æŽ§åˆ¶åžƒåœ¾æ”¶é›†å¾ªçŽ¯ï¼š 垃圾收集器间æ‡çއ å’Œ 垃圾收集器æ¥è¿›å€çŽ‡ã€‚ 这两个数å—都使用百分数为å•ä½ ï¼ˆä¾‹å¦‚ï¼šå€¼ 100 在内部表示 1 )。
垃圾收集器间æ‡çŽ‡æŽ§åˆ¶ç€æ”¶é›†å™¨éœ€è¦åœ¨å¼€å¯æ–°çš„循环å‰è¦ç‰å¾…多久。 增大这个值会å‡å°‘æ”¶é›†å™¨çš„ç§¯æžæ€§ã€‚ 当这个值比 100 å°çš„æ—¶å€™ï¼Œæ”¶é›†å™¨åœ¨å¼€å¯æ–°çš„循环å‰ä¸ä¼šæœ‰ç‰å¾…。 设置这个值为 200 就会让收集器ç‰åˆ°æ€»å†…å˜ä½¿ç”¨é‡è¾¾åˆ° 之å‰çš„䏤倿—¶æ‰å¼€å§‹æ–°çš„循环。
垃圾收集器æ¥è¿›å€çŽ‡æŽ§åˆ¶ç€æ”¶é›†å™¨è¿ä½œé€Ÿåº¦ç›¸å¯¹äºŽå†…å˜åˆ†é…速度的å€çŽ‡ã€‚ 增大这个值ä¸ä»…ä¼šè®©æ”¶é›†å™¨æ›´åŠ ç§¯æžï¼Œè¿˜ä¼šå¢žåŠ æ¯ä¸ªå¢žé‡æ¥éª¤çš„长度。 ä¸è¦æŠŠè¿™ä¸ªå€¼è®¾å¾—å°äºŽ 100 , é‚£æ ·çš„è¯æ”¶é›†å™¨å°±å·¥ä½œçš„太慢了以至于永远都干ä¸å®Œä¸€ä¸ªå¾ªçŽ¯ã€‚ 默认值是 200 ,这表示收集器以内å˜åˆ†é…的“两å€â€é€Ÿå·¥ä½œã€‚
å¦‚æžœä½ æŠŠæ¥è¿›å€çŽ‡è®¾ä¸ºä¸€ä¸ªéžå¸¸å¤§çš„æ•°å— ï¼ˆæ¯”ä½ çš„ç¨‹åºå¯èƒ½ç”¨åˆ°çš„å—节数还大 10% ), 收集器的行为就åƒä¸€ä¸ª stop-the-world 收集器。 接ç€ä½ 若把间æ‡çŽ‡è®¾ä¸º 200 , 收集器的行为就和过去的 Lua ç‰ˆæœ¬ä¸€æ ·äº†ï¼š æ¯æ¬¡ Lua 使用的内å˜ç¿»å€æ—¶ï¼Œå°±åšä¸€æ¬¡å®Œæ•´çš„æ”¶é›†ã€‚
ä½ å¯ä»¥é€šè¿‡åœ¨ C ä¸è°ƒç”¨ lua_gc
或在 Lua ä¸è°ƒç”¨ collectgarbage
æ¥æ”¹å˜è¿™ä¿©æ•°å—。
这两个函数也å¯ä»¥ç”¨æ¥ç›´æŽ¥æŽ§åˆ¶æ”¶é›†å™¨ï¼ˆä¾‹å¦‚åœæ¢å®ƒæˆ–é‡å¯å®ƒï¼‰ã€‚
ä½ å¯ä»¥ä¸ºè¡¨è®¾å®šåžƒåœ¾æ”¶é›†çš„元方法, 对于完全用户数æ®ï¼ˆå‚è§ §2.4), 则需è¦ä½¿ç”¨ C API 。 该元方法被称为 终结器。 终结器å…è®¸ä½ é…åˆ Lua 的垃圾收集器åšä¸€äº›é¢å¤–的资æºç®¡ç†å·¥ä½œ ï¼ˆä¾‹å¦‚å…³é—æ–‡ä»¶ã€ç½‘络或数æ®åº“è¿žæŽ¥ï¼Œæˆ–æ˜¯é‡Šæ”¾ä¸€äº›ä½ è‡ªå·±çš„å†…å˜ï¼‰ã€‚
如果è¦è®©ä¸€ä¸ªå¯¹è±¡ï¼ˆè¡¨æˆ–用户数æ®ï¼‰åœ¨æ”¶é›†è¿‡ç¨‹ä¸è¿›å…¥ç»ˆç»“æµç¨‹ï¼Œ
ä½ å¿…é¡» æ ‡è®° 它需è¦è§¦å‘终结器。
å½“ä½ ä¸ºä¸€ä¸ªå¯¹è±¡è®¾ç½®å…ƒè¡¨æ—¶ï¼Œè‹¥æ¤åˆ»è¿™å¼ 元表ä¸ç”¨ä¸€ä¸ªä»¥å—符串
"__gc" ä¸ºç´¢å¼•çš„åŸŸï¼Œé‚£ä¹ˆå°±æ ‡è®°äº†è¿™ä¸ªå¯¹è±¡éœ€è¦è§¦å‘终结器。
注æ„ï¼šå¦‚æžœä½ ç»™å¯¹è±¡è®¾ç½®äº†ä¸€ä¸ªæ²¡æœ‰ __gc
åŸŸçš„å…ƒè¡¨ï¼Œä¹‹åŽæ‰ç»™å…ƒè¡¨åŠ ä¸Šè¿™ä¸ªåŸŸï¼Œ
é‚£ä¹ˆè¿™ä¸ªå¯¹è±¡æ˜¯æ²¡æœ‰è¢«æ ‡è®°æˆéœ€è¦è§¦å‘终结器的。
ç„¶è€Œï¼Œä¸€æ—¦å¯¹è±¡è¢«æ ‡è®°ï¼Œ
ä½ è¿˜æ˜¯å¯ä»¥è‡ªç”±çš„æ”¹å˜å…¶å…ƒè¡¨ä¸çš„ __gc 域的。
å½“ä¸€ä¸ªè¢«æ ‡è®°çš„å¯¹è±¡æˆä¸ºäº†åžƒåœ¾åŽï¼Œ
垃圾收集器并ä¸ä¼šç«‹åˆ»å›žæ”¶å®ƒã€‚
å–而代之的是,Lua 会将其置入一个链表。
在收集完æˆåŽï¼ŒLua å°†é历这个链表。
Lua 会检查æ¯ä¸ªé“¾è¡¨ä¸çš„对象的 __gc
å…ƒæ–¹æ³•ï¼šå¦‚æžœæ˜¯ä¸€ä¸ªå‡½æ•°ï¼Œé‚£ä¹ˆå°±ä»¥å¯¹è±¡ä¸ºå”¯ä¸€å‚æ•°è°ƒç”¨å®ƒï¼›
å¦åˆ™ç›´æŽ¥å¿½ç•¥å®ƒã€‚
åœ¨æ¯æ¬¡åžƒåœ¾æ”¶é›†å¾ªçŽ¯çš„æœ€åŽé˜¶æ®µï¼Œ æœ¬æ¬¡å¾ªçŽ¯ä¸æ£€æµ‹åˆ°çš„需è¦è¢«å›žæ”¶ä¹‹å¯¹è±¡ï¼Œ å…¶ç»ˆç»“å™¨çš„è§¦å‘æ¬¡åºæŒ‰å½“åˆç»™å¯¹è±¡ä½œéœ€è¦è§¦å‘ç»ˆç»“å™¨çš„æ ‡è®°ä¹‹æ¬¡åºçš„逆åºè¿›è¡Œï¼› 这就是说,第一个被调用的终结器是程åºä¸æœ€åŽä¸€ä¸ªè¢«æ ‡è®°çš„对象所æºçš„那个。 æ¯ä¸ªç»ˆç»“器的è¿è¡Œå¯èƒ½å‘生在执行常规代ç 过程ä¸çš„ä»»æ„一刻。
由于被回收的对象还需è¦è¢«ç»ˆç»“器使用, 该对象(以åŠä»…能通过它访问到的其它对象)一定会被 Lua 夿´»ã€‚ é€šå¸¸ï¼Œå¤æ´»æ˜¯çŸæš‚的,对象所属内å˜ä¼šåœ¨ä¸‹ä¸€ä¸ªåžƒåœ¾æ”¶é›†å¾ªçŽ¯é‡Šæ”¾ã€‚ ç„¶åŽï¼Œè‹¥ç»ˆç»“器åˆå°†å¯¹è±¡ä¿å˜åŽ»ä¸€äº›å…¨å±€çš„åœ°æ–¹ (例如:放在一个全局å˜é‡é‡Œï¼‰ï¼Œè¿™æ¬¡å¤æ´»å°±æŒç»ç”Ÿæ•ˆäº†ã€‚ æ¤å¤–,如果在终结器ä¸å¯¹ä¸€ä¸ªæ£è¿›å…¥ç»ˆç»“æµç¨‹çš„å¯¹è±¡å†æ¬¡åšä¸€æ¬¡æ ‡è®°è®©å®ƒè§¦å‘终结器, åªè¦è¿™ä¸ªå¯¹è±¡åœ¨ä¸‹ä¸ªå¾ªçޝä¸ä¾æ—§ä¸å¯è¾¾ï¼Œå®ƒçš„终结函数还会å†è°ƒç”¨ä¸€æ¬¡ã€‚ æ— è®ºæ˜¯å“ªç§æƒ…况, 对象所属内å˜ä»…在垃圾收集循环ä¸è¯¥å¯¹è±¡ä¸å¯è¾¾ä¸” æ²¡æœ‰è¢«æ ‡è®°æˆéœ€è¦è§¦å‘终结器æ‰ä¼šè¢«é‡Šæ”¾ã€‚
å½“ä½ å…³é—ä¸€ä¸ªçŠ¶æ€æœºï¼ˆå‚è§ lua_close),
Lua å°†è°ƒç”¨æ‰€æœ‰è¢«æ ‡è®°äº†éœ€è¦è§¦å‘终结器对象的终结过程,
其次åºä¸ºæ ‡è®°æ¬¡åºçš„逆åºã€‚
在这个过程ä¸ï¼Œä»»ä½•ç»ˆç»“å™¨å†æ¬¡æ ‡è®°å¯¹è±¡çš„行为都ä¸ä¼šç”Ÿæ•ˆã€‚
弱表 æŒ‡å†…éƒ¨å…ƒç´ ä¸º 弱引用 的表。 垃圾收集器会忽略掉弱引用。 æ¢å¥è¯è¯´ï¼Œå¦‚果一个对象åªè¢«å¼±å¼•用引用到, 垃圾收集器就会回收这个对象。
ä¸€å¼ å¼±è¡¨å¯ä»¥æœ‰å¼±é”®æˆ–是弱值,也å¯ä»¥é”®å€¼éƒ½æ˜¯å¼±å¼•用。
嫿œ‰å¼±å€¼çš„表å…è®¸æ”¶é›†å™¨å›žæ”¶å®ƒçš„å€¼ï¼Œä½†ä¼šé˜»æ¢æ”¶é›†å™¨å›žæ”¶å®ƒçš„键。
è‹¥ä¸€å¼ è¡¨çš„é”®å€¼å‡ä¸ºå¼±å¼•用,
那么收集器å¯ä»¥å›žæ”¶å…¶ä¸çš„ä»»æ„键和值。
任何情况下,åªè¦é”®æˆ–值的任æ„一项被回收,
相关è”的键值对都会从表ä¸ç§»é™¤ã€‚
ä¸€å¼ è¡¨çš„å…ƒè¡¨ä¸çš„ __mode 域控制ç€è¿™å¼ 表的弱属性。
当 __mode 域是一个包å«å—符 'k'
çš„å—ç¬¦ä¸²æ—¶ï¼Œè¿™å¼ è¡¨çš„æ‰€æœ‰é”®çš†ä¸ºå¼±å¼•ç”¨ã€‚
当 __mode 域是一个包å«å—符 'v'
çš„å—ç¬¦ä¸²æ—¶ï¼Œè¿™å¼ è¡¨çš„æ‰€æœ‰å€¼çš†ä¸ºå¼±å¼•ç”¨ã€‚
属性为弱键强值的表也被称为 暂时表。 å¯¹äºŽä¸€å¼ æš‚æ—¶è¡¨ï¼Œ 它的值是å¦å¯è¾¾ä»…å–决于其对应键是å¦å¯è¾¾ã€‚ 特别注æ„,如果表内的一个键仅仅被其值所关è”引用, 这个键值对将被表内移除。
å¯¹ä¸€å¼ è¡¨çš„å¼±å±žæ€§çš„ä¿®æ”¹ä»…åœ¨ä¸‹æ¬¡æ”¶é›†å¾ªçŽ¯æ‰ç”Ÿæ•ˆã€‚ å°¤å…¶æ˜¯å½“ä½ æŠŠè¡¨ç”±å¼±æ”¹å¼ºï¼ŒLua 还是有å¯èƒ½åœ¨ä¿®æ”¹ç”Ÿæ•ˆå‰å›žæ”¶è¡¨å†…一些项目。
åªæœ‰é‚£äº›æœ‰æ˜¾å¼æž„é€ è¿‡ç¨‹çš„å¯¹è±¡æ‰ä¼šä»Žå¼±è¡¨ä¸ç§»é™¤ã€‚ 值,例如数å—å’Œè½»é‡ C 函数,ä¸å—垃圾收集器管辖, å› æ¤ä¸ä¼šä»Žå¼±è¡¨ä¸ç§»é™¤ (除éžå®ƒä»¬çš„å…³è”项被回收)。 虽然å—符串å—垃圾回收器管辖, 但它们没有显å¼çš„æž„é€ è¿‡ç¨‹ï¼Œæ‰€ä»¥ä¹Ÿä¸ä¼šä»Žå¼±è¡¨ä¸ç§»é™¤ã€‚
å¼±è¡¨é’ˆå¯¹å¤æ´»çš„对象 (指那些æ£åœ¨èµ°ç»ˆç»“æµç¨‹ï¼Œä»…能被终结器访问的对象) 有ç€ç‰¹æ®Šçš„行为。 弱值引用的对象,在è¿è¡Œå®ƒä»¬çš„终结器å‰å°±è¢«ç§»é™¤äº†ï¼Œ 而弱键引用的对象则è¦ç‰åˆ°ç»ˆç»“器è¿è¡Œå®Œæ¯•åŽï¼Œåˆ°ä¸‹æ¬¡æ”¶é›†å½“对象真的被释放时æ‰è¢«ç§»é™¤ã€‚ 这个行为使得终结器è¿è¡Œæ—¶å¾—ä»¥è®¿é—®åˆ°ç”±è¯¥å¯¹è±¡åœ¨å¼±è¡¨ä¸æ‰€å…³è”的属性。
å¦‚æžœä¸€å¼ å¼±è¡¨åœ¨å½“æ¬¡æ”¶é›†å¾ªçŽ¯å†…çš„å¤æ´»å¯¹è±¡ä¸ï¼Œ 那么在下个循环å‰è¿™å¼ 表有å¯èƒ½æœªè¢«æ£ç¡®åœ°æ¸…ç†ã€‚
Lua 支æŒåç¨‹ï¼Œä¹Ÿå« ååŒå¼å¤šçº¿ç¨‹ã€‚ 一个å程在 Lua ä¸ä»£è¡¨äº†ä¸€æ®µç‹¬ç«‹çš„æ‰§è¡Œçº¿ç¨‹ã€‚ 然而,与多线程系统ä¸çš„线程的区别在于, å程仅在显å¼è°ƒç”¨ä¸€ä¸ªè®©å‡ºï¼ˆyieldï¼‰å‡½æ•°æ—¶æ‰æŒ‚起当å‰çš„æ‰§è¡Œã€‚
调用函数
coroutine.create
å¯åˆ›å»ºä¸€ä¸ªå程。
å…¶å”¯ä¸€çš„å‚æ•°æ˜¯è¯¥å程的主函数。
create 函数åªè´Ÿè´£æ–°å»ºä¸€ä¸ªåç¨‹å¹¶è¿”å›žå…¶å¥æŸ„
(一个 thread 类型的对象);
而ä¸ä¼šå¯åŠ¨è¯¥å程。
调用
coroutine.resume
函数执行一个å程。
第一次调用
coroutine.resume
æ—¶ï¼Œç¬¬ä¸€ä¸ªå‚æ•°åº”ä¼ å…¥
coroutine.create
返回的线程对象,然åŽå程从其主函数的第一行开始执行。
ä¼ é€’ç»™
coroutine.resume
çš„å…¶ä»–å‚æ•°å°†ä½œä¸ºåç¨‹ä¸»å‡½æ•°çš„å‚æ•°ä¼ 入。
å程å¯åЍ之åŽï¼Œå°†ä¸€ç›´è¿è¡Œåˆ°å®ƒç»ˆæ¢æˆ– 让出。
å程的è¿è¡Œå¯èƒ½è¢«ä¸¤ç§æ–¹å¼ç»ˆæ¢ï¼š
æ£å¸¸é€”径是主函数返回
(显å¼è¿”回或è¿è¡Œå®Œæœ€åŽä¸€æ¡æŒ‡ä»¤ï¼‰ï¼›
éžæ£å¸¸é€”径是å‘生了一个未被æ•获的错误。
对于æ£å¸¸ç»“æŸï¼Œ
coroutine.resume 将返回 true,
并接上å程主函数的返回值。
当错误å‘生时,
coroutine.resume 将返回 false
与错误消æ¯ã€‚
通过调用
coroutine.yield 使åç¨‹æš‚åœæ‰§è¡Œï¼Œè®©å‡ºæ‰§è¡Œæƒã€‚
å程让出时,对应的最近 coroutine.resume
函数会立刻返回,å³ä½¿è¯¥è®©å‡ºæ“作å‘生在内嵌函数调用ä¸
(å³ä¸åœ¨ä¸»å‡½æ•°ï¼Œä½†åœ¨ä¸»å‡½æ•°ç›´æŽ¥æˆ–间接调用的函数内部)。
在å程让出的情况下,
coroutine.resume 也会返回 true,
å¹¶åŠ ä¸Šä¼ ç»™
coroutine.yield çš„å‚æ•°ã€‚
当下次é‡å¯åŒä¸€ä¸ªå程时,
å程会接ç€ä»Žè®©å‡ºç‚¹ç»§ç»æ‰§è¡Œã€‚
æ¤æ—¶ï¼Œæ¤å‰è®©å‡ºç‚¹å¤„对 coroutine.yield 的调用
ä¼šè¿”å›žï¼Œè¿”å›žå€¼ä¸ºä¼ ç»™
coroutine.resume
çš„ç¬¬ä¸€ä¸ªå‚æ•°ä¹‹å¤–çš„å…¶ä»–å‚æ•°ã€‚
与
coroutine.create 类似,
coroutine.wrap 函数也会创建一个å程。
ä¸åŒä¹‹å¤„在于,它ä¸è¿”回å程本身,而是返回一个函数。
调用这个函数将å¯åŠ¨è¯¥å程。
ä¼ é€’ç»™è¯¥å‡½æ•°çš„ä»»ä½•å‚æ•°å‡å½“作 coroutine.resume çš„é¢å¤–傿•°ã€‚
coroutine.wrap
返回
coroutine.resume
的所有返回值,除了第一个返回值(布尔型的错误ç )。
å’Œ coroutine.resume ä¸åŒï¼Œ
coroutine.wrap
ä¸ä¼šæ•获错误;
è€Œæ˜¯å°†ä»»ä½•é”™è¯¯éƒ½ä¼ æ’给调用者。
下é¢çš„代ç 展示了一个å程工作的范例:
function foo (a)
print("foo", a)
return coroutine.yield(2*a)
end
co = coroutine.create(function (a,b)
print("co-body", a, b)
local r = foo(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
ä½ ä¹Ÿå¯ä»¥é€šè¿‡ C API æ¥åˆ›å»ºåŠæ“作å程:
å‚è§å‡½æ•°
lua_newthread,
lua_resume,
ä»¥åŠ lua_yield。
è¿™ä¸€ç« æè¿°äº† Lua çš„è¯æ³•ã€è¯æ³•å’Œå¥æ³•。 æ¢å¥è¯è¯´ï¼Œæœ¬ç« æè¿°å“ªäº›ç¬¦è®°æ˜¯æœ‰æ•ˆçš„, 它们如何被组åˆèµ·æ¥ï¼Œè¿™äº›ç»„åˆæ–¹å¼æœ‰ä»€ä¹ˆå«ä¹‰ã€‚
关于è¯è¨€çš„æž„æˆæ¦‚念将用常è§çš„æ‰©å±• BNF 表达å¼å†™å‡ºã€‚ ä¹Ÿå°±æ˜¯è¿™ä¸ªæ ·å: {a} 表示 0 或多个 a, [a] 表示一个å¯é€‰çš„ a。 å¯ä»¥è¢«åˆ†è§£çš„éžæœ€ç»ˆç¬¦å·ä¼šè¿™æ ·å†™ non-terminal , 关键å—会写æˆè¿™æ · kword, 而其它ä¸èƒ½è¢«åˆ†è§£çš„æœ€ç»ˆç¬¦å·åˆ™å†™æˆè¿™æ · ‘=’ 。 完整的 Lua è¯æ³•å¯ä»¥åœ¨æœ¬æ‰‹å†Œæœ€åŽä¸€ç« §9 找到。
Lua è¯è¨€çš„æ ¼å¼è‡ªç”±ã€‚ å®ƒä¼šå¿½ç•¥è¯æ³•å…ƒç´ ï¼ˆç¬¦è®°ï¼‰é—´çš„ç©ºæ ¼ï¼ˆåŒ…æ‹¬æ¢è¡Œï¼‰å’Œæ³¨é‡Šï¼Œ 仅把它们看作为åå—和关键å—间的分割符。
Lua ä¸çš„ åå— ï¼ˆä¹Ÿè¢«ç§°ä¸º æ ‡è¯†ç¬¦ï¼‰ å¯ä»¥æ˜¯ç”±éžæ•°å—打头的任æ„å—æ¯ä¸‹åˆ’çº¿å’Œæ•°å—æž„æˆçš„å—符串。 æ ‡è¯†ç¬¦å¯ç”¨äºŽå¯¹å˜é‡ã€è¡¨çš„域ã€ä»¥åŠæ ‡ç¾å‘½å。
下列 å…³é”®å— æ˜¯ä¿ç•™çš„,ä¸å¯ç”¨äºŽåå—:
and break do else elseif end
false for function goto if in
local nil not or repeat return
then true until while
Lua è¯è¨€å¯¹å¤§å°å†™æ•感:
and 是一个ä¿ç•™å—,但 And 与 AND
则是两个ä¸åŒçš„æœ‰æ•ˆåå—。
作为一个约定,程åºåº”é¿å…åˆ›å»ºä»¥ä¸‹åˆ’çº¿åŠ ä¸€ä¸ªæˆ–å¤šä¸ªå¤§å†™å—æ¯æž„æˆçš„åå—
(例如 _VERSION)。
下列å—符串是å¦å¤–一些符记:
+ - * / % ^ #
& ~ | << >> //
== ~= <= >= < > =
( ) { } [ ] ::
; : , . .. ...
å—é¢ä¸² å¯ä»¥ç”¨å•引巿ˆ–åŒå¼•å·æ‹¬èµ·ã€‚
å—é¢ä¸²å†…部å¯ä»¥åŒ…å«ä¸‹åˆ— C é£Žæ ¼çš„è½¬ä¹‰ä¸²ï¼š
'\a' (å“铃),
'\b' ï¼ˆé€€æ ¼ï¼‰ï¼Œ
'\f' (æ¢é¡µï¼‰ï¼Œ
'\n' (æ¢è¡Œï¼‰ï¼Œ
'\r' (回车),
'\t' (横项制表),
'\v' (纵å‘制表),
'\\' ï¼ˆåæ–œæ ),
'\"' (åŒå¼•å·ï¼‰ï¼Œ
ä»¥åŠ '\'' (å•引å·)。
åœ¨åæ–œæ åŽè·Ÿä¸€ä¸ªçœŸæ£çš„æ¢è¡Œç‰ä»·äºŽåœ¨å—符串ä¸å†™ä¸€ä¸ªæ¢è¡Œç¬¦ã€‚
转义串 '\z' 会忽略其åŽçš„一系列空白符,包括æ¢è¡Œï¼›
å®ƒåœ¨ä½ éœ€è¦å¯¹ä¸€ä¸ªå¾ˆé•¿çš„å—ç¬¦ä¸²å¸¸é‡æ–行为多行并希望在æ¯ä¸ªæ–°è¡Œä¿æŒç¼©è¿›æ—¶éžå¸¸æœ‰ç”¨ã€‚
Lua ä¸çš„å—符串å¯ä»¥ä¿å˜ä»»æ„ 8 ä½å€¼ï¼Œå…¶ä¸åŒ…括用 '\0' 表示的 0 。
ä¸€èˆ¬è€Œè¨€ï¼Œä½ å¯ä»¥ç”¨å—符的数å—值æ¥è¡¨ç¤ºè¿™ä¸ªå—符。
æ–¹å¼æ˜¯ç”¨è½¬ä¹‰ä¸² \xXX,
æ¤å¤„çš„ XX 必须是æ°å¥½ä¸¤ä¸ªå—符的 16 进制数。
æˆ–è€…ä½ ä¹Ÿå¯ä»¥ä½¿ç”¨è½¬ä¹‰ä¸² \ddd ,
这里的 ddd 是一到三个å进制数å—。
(注æ„ï¼Œå¦‚æžœåœ¨è½¬ä¹‰ç¬¦åŽæŽ¥ç€æ°å·§æ˜¯ä¸€ä¸ªæ•°å—符å·çš„è¯ï¼Œ
ä½ å°±å¿…é¡»åœ¨è¿™ä¸ªè½¬ä¹‰å½¢å¼ä¸å†™æ»¡ä¸‰ä¸ªæ•°å—。)
对于用 UTF-8 ç¼–ç çš„ Unicode å—ç¬¦ï¼Œä½ å¯ä»¥ç”¨
转义符 \u{XXX} æ¥è¡¨ç¤º
(这里必须有一对花括å·ï¼‰ï¼Œ
æ¤å¤„çš„ XXX 是用 16 进制表示的å—符编å·ã€‚
å—é¢ä¸²è¿˜å¯ä»¥ç”¨ä¸€ç§ é•¿æ‹¬å· æ‹¬èµ·æ¥çš„æ–¹å¼å®šä¹‰ã€‚
我们把两个æ£çš„æ–¹æ‹¬å·é—´æ’å…¥ n 个ç‰å·å®šä¹‰ä¸º 第 n 级开长括å·ã€‚
就是说,0 级开的长括å·å†™ä½œ [[ , 一级开长括å·å†™ä½œ [=[ ,
如æ¤ç‰ç‰ã€‚
é—长括å·ä¹Ÿä½œç±»ä¼¼å®šä¹‰ï¼›
举个例å,4 级å的长括å·å†™ä½œ ]====] 。
一个 é•¿å—é¢ä¸² å¯ä»¥ç”±ä»»ä½•一级的开长括å·å¼€å§‹ï¼Œè€Œç”±ç¬¬ä¸€ä¸ªç¢°åˆ°çš„åŒçº§çš„é—长括å·ç»“æŸã€‚
è¿™ç§æ–¹å¼æè¿°çš„å—符串å¯ä»¥åŒ…å«ä»»ä½•东西,当然特定级别的å长括å·é™¤å¤–。
æ•´ä¸ªè¯æ³•分æžè¿‡ç¨‹å°†ä¸å—分行é™åˆ¶ï¼Œä¸å¤„ç†ä»»ä½•转义符,并且忽略掉任何ä¸åŒçº§åˆ«çš„长括å·ã€‚
å…¶ä¸ç¢°åˆ°çš„任何形å¼çš„æ¢è¡Œä¸²ï¼ˆå›žè½¦ã€æ¢è¡Œã€å›žè½¦åŠ æ¢è¡Œã€æ¢è¡ŒåŠ å›žè½¦ï¼‰ï¼Œéƒ½ä¼šè¢«è½¬æ¢ä¸ºå•个æ¢è¡Œç¬¦ã€‚
å—é¢ä¸²ä¸çš„æ¯ä¸ªä¸è¢«ä¸Šè¿°è§„则影å“çš„å—节都呈现为本身。 然而,Lua æ˜¯ç”¨æ–‡æœ¬æ¨¡å¼æ‰“å¼€æºæ–‡ä»¶è§£æžçš„, 一些系统的文件æ“作函数对æŸäº›æŽ§åˆ¶å—符的处ç†å¯èƒ½æœ‰é—®é¢˜ã€‚ å› æ¤ï¼Œå¯¹äºŽéžæ–‡æœ¬æ•°æ®ï¼Œç”¨å¼•å·æ‹¬èµ·æ¥å¹¶æ˜¾å¼æŒ‰è½¬ä¹‰ç¬¦è§„则æ¥è¡¨è¿°æ›´å®‰å…¨ã€‚
为了方便起è§ï¼Œ
当一个开长括å·åŽç´§æŽ¥ä¸€ä¸ªæ¢è¡Œç¬¦æ—¶ï¼Œ
这个æ¢è¡Œç¬¦ä¸ä¼šæ”¾åœ¨å—符串内。
举个例å,å‡è®¾ä¸€ä¸ªç³»ç»Ÿä½¿ç”¨ ASCII ç
ï¼ˆæ¤æ—¶ 'a' ç¼–ç 为 97 ,
æ¢è¡Œç¼–ç 为 10 ,'1' ç¼–ç 为 49 ),
下é¢äº”ç§æ–¹å¼æè¿°äº†å®Œå…¨ç›¸åŒçš„å—符串:
a = 'alo\n123"'
a = "alo\n123\""
a = '\97lo\10\04923"'
a = [[alo
123"]]
a = [==[
alo
123"]==]
æ•°å—å¸¸é‡ ï¼ˆæˆ–ç§°ä¸º æ•°å—é‡ï¼‰
å¯ä»¥ç”±å¯é€‰çš„å°æ•°éƒ¨åˆ†å’Œå¯é€‰çš„å为底的指数部分构æˆï¼Œ
指数部分用å—符 'e' 或 'E' æ¥æ ‡è®°ã€‚
Lua 也接å—以 0x 或 0X 开头的 16 进制常é‡ã€‚
16 进制常é‡ä¹ŸæŽ¥å—å°æ•°åŠ æŒ‡æ•°éƒ¨åˆ†çš„å½¢å¼ï¼ŒæŒ‡æ•°éƒ¨åˆ†æ˜¯ä»¥äºŒä¸ºåº•,
用å—符 'p' 或 'P' æ¥æ ‡è®°ã€‚
æ•°å—常é‡ä¸åŒ…å«å°æ•°ç‚¹æˆ–指数部分时,被认为是一个浮点数;
å¦åˆ™è¢«è®¤ä¸ºæ˜¯ä¸€ä¸ªæ•´æ•°ã€‚
䏋颿œ‰ä¸€äº›åˆæ³•的整数常é‡çš„例å:
3 345 0xff 0xBEBADA
ä»¥ä¸‹ä¸ºåˆæ³•的浮点常é‡ï¼š
3.0 3.1416 314.16e-2 0.31416E1 34e1
0x0.1E 0xA23p-4 0X1.921FB54442D18P+1
在å—ç¬¦ä¸²å¤–çš„ä»»ä½•åœ°æ–¹å‡ºçŽ°ä»¥åŒæ¨ªçº¿ (--) 开头的部分是 注释 。
如果 -- åŽæ²¡æœ‰ç´§è·Ÿç€ä¸€ä¸ªå¼€å¤§æ‹¬å·ï¼Œ
该注释为 çŸæ³¨é‡Šï¼Œ
注释到当å‰è¡Œæœ«æˆªè‡³ã€‚
å¦åˆ™ï¼Œè¿™æ˜¯ä¸€æ®µ 长注释 ,
注释区一直维æŒåˆ°å¯¹åº”çš„é—长括å·ã€‚
长注释通常用于临时å±è”½æŽ‰ä¸€å¤§æ®µä»£ç 。
å˜é‡æ˜¯å‚¨å˜å€¼çš„地方。 Lua 䏿œ‰ä¸‰ç§å˜é‡ï¼š 全局å˜é‡ã€å±€éƒ¨å˜é‡å’Œè¡¨çš„域。
å•个åå—å¯ä»¥æŒ‡ä»£ä¸€ä¸ªå…¨å±€å˜é‡ä¹Ÿå¯ä»¥æŒ‡ä»£ä¸€ä¸ªå±€éƒ¨å˜é‡ (或者是一个函数的形å‚,这是一ç§ç‰¹æ®Šå½¢å¼çš„局部å˜é‡ï¼‰ã€‚
var ::= Name
åå—æŒ‡ §3.1 ä¸å®šä¹‰çš„æ ‡è¯†ç¬¦ã€‚
所有没有显å¼å£°æ˜Žä¸ºå±€éƒ¨å˜é‡ï¼ˆå‚è§ §3.3.7) çš„å˜é‡å都被当åšå…¨å±€å˜é‡ã€‚ 局部å˜é‡æœ‰å…¶ 作用范围 : 局部å˜é‡å¯ä»¥è¢«å®šä¹‰åœ¨å®ƒä½œç”¨èŒƒå›´ä¸çš„函数自由使用(å‚è§ §3.5)。
在å˜é‡çš„首次赋值之å‰ï¼Œå˜é‡çš„值å‡ä¸º nil。
方括å·è¢«ç”¨æ¥å¯¹è¡¨ä½œç´¢å¼•:
var ::= prefixexp ‘[’ exp ‘]’
对全局å˜é‡ä»¥åŠè¡¨çš„域之访问的å«ä¹‰å¯ä»¥é€šè¿‡å…ƒè¡¨æ¥æ”¹å˜ã€‚
以索引方å¼è®¿é—®ä¸€ä¸ªå˜é‡ t[i] ç‰ä»·äºŽ
调用 gettable_event(t,i)。
(å‚è§ §2.4 ,有一份完整的关于
gettable_event 函数的说明。
这个函数并没有在 lua ä¸å®šä¹‰å‡ºæ¥ï¼Œä¹Ÿä¸èƒ½åœ¨ lua ä¸è°ƒç”¨ã€‚这里我们把æåˆ°å®ƒåªæ˜¯æ–¹ä¾¿è¯´æ˜Žé—®é¢˜ã€‚)
var.Name è¿™ç§è¯æ³•åªæ˜¯ä¸€ä¸ªè¯æ³•糖,用æ¥è¡¨ç¤º
var["Name"]:
var ::= prefixexp ‘.’ Name
对全局å˜é‡ x çš„æ“作ç‰ä»·äºŽæ“作
_ENV.x。
由于代ç å—编译的方å¼ï¼Œ
_ENV 永远也ä¸å¯èƒ½æ˜¯ä¸€ä¸ªå…¨å±€åå— ï¼ˆå‚è§ §2.2)。
Lua æ”¯æŒæ‰€æœ‰ä¸Ž Pascal 或是 C 类似的常è§å½¢å¼çš„è¯å¥ï¼Œ 这个集åˆåŒ…括赋值,控制结构,函数调用,还有å˜é‡å£°æ˜Žã€‚
è¯å¥å—是一个è¯å¥åºåˆ—ï¼Œå®ƒä»¬ä¼šæŒ‰æ¬¡åºæ‰§è¡Œï¼š
block ::= {stat}
Lua æ”¯æŒ ç©ºè¯å¥ï¼Œ ä½ å¯ä»¥ç”¨åˆ†å·åˆ†å‰²è¯å¥ï¼Œä¹Ÿå¯ä»¥ä»¥åˆ†å·å¼€å§‹ä¸€ä¸ªè¯å¥å—, 或是连ç€å†™ä¸¤ä¸ªåˆ†å·ï¼š
stat ::= ‘;’
函数调用和赋值è¯å¥éƒ½å¯èƒ½ä»¥ä¸€ä¸ªå°æ‹¬å·æ‰“头, è¿™å¯èƒ½è®© Lua çš„è¯æ³•产生æ§ä¹‰ã€‚ 我们æ¥çœ‹çœ‹ä¸‹é¢çš„代ç 片æ–:
a = b + c
(print or io.write)('done')
ä»Žè¯æ³•上说,å¯èƒ½æœ‰ä¸¤ç§è§£é‡Šæ–¹å¼ï¼š
a = b + c(print or io.write)('done')
a = b + c; (print or io.write)('done')
当å‰çš„è§£æžå™¨æ€»æ˜¯ç”¨ç¬¬ä¸€ç§ç»“æž„æ¥è§£æžï¼Œ 它会将开括å·çœ‹æˆå‡½æ•°è°ƒç”¨çš„傿•°ä¼ 递开始处。 为了é¿å…è¿™ç§äºŒä¹‰æ€§ï¼Œ 在一æ¡è¯å¥ä»¥å°æ‹¬å·å¼€å¤´æ—¶ï¼Œå‰é¢æ”¾ä¸€ä¸ªåˆ†å·æ˜¯ä¸ªå¥½ä¹ 惯:
;(print or io.write)('done')
一个è¯å¥å—å¯ä»¥è¢«æ˜¾å¼çš„å®šç•Œä¸ºå•æ¡è¯å¥ï¼š
stat ::= do block end
显å¼çš„对一个å—å®šç•Œé€šå¸¸ç”¨æ¥æŽ§åˆ¶å†…éƒ¨å˜é‡å£°æ˜Žçš„作用域。 有时,显å¼å®šç•Œä¹Ÿç”¨äºŽåœ¨ä¸€ä¸ªè¯å¥å—ä¸é—´æ’å…¥ return (å‚è§ §3.3.4)。
Lua 的一个编译å•元被称为一个 代ç å—。 ä»Žå¥æ³•æž„æˆä¸Šè®²ï¼Œä¸€ä¸ªä»£ç å—就是一个è¯å¥å—。
chunk ::= block
Lua 把一个代ç å—当作一个拥有ä¸å®šå‚数的匿å函数
(å‚è§§3.4.11)æ¥å¤„ç†ã€‚
æ£æ˜¯è¿™æ ·ï¼Œä»£ç å—内å¯ä»¥å®šä¹‰å±€éƒ¨å˜é‡ï¼Œå®ƒå¯ä»¥æŽ¥æ”¶å‚数,返回若干值。
æ¤å¤–,这个匿å函数在编译时还为它的作用域绑定了一个外部局部å˜é‡
_ENV (å‚è§ §2.2)。
该函数总是把 _ENV 作为它唯一的一个上值,
å³ä½¿è¿™ä¸ªå‡½æ•°ä¸ä½¿ç”¨è¿™ä¸ªå˜é‡ï¼Œå®ƒä¹Ÿå˜åœ¨ã€‚
代ç å—å¯ä»¥è¢«ä¿å˜åœ¨æ–‡ä»¶ä¸ï¼Œä¹Ÿå¯ä»¥ä½œä¸ºå®¿ä¸»ç¨‹åºå†…部的一个å—符串。 è¦æ‰§è¡Œä¸€ä¸ªä»£ç å—, 首先è¦è®© Lua åŠ è½½ 它, 将代ç å—ä¸çš„代ç 预编译æˆè™šæ‹Ÿæœºä¸çš„æŒ‡ä»¤ï¼Œ 而åŽï¼ŒLua 用虚拟机解释器æ¥è¿è¡Œç¼–译åŽçš„代ç 。
代ç å—å¯ä»¥è¢«é¢„编译为二进制形å¼ï¼›
å‚è§ç¨‹åº luac 以åŠå‡½æ•° string.dump å¯èŽ·å¾—æ›´å¤šç»†èŠ‚ã€‚
用æºç 表示的程åºå’Œç¼–译åŽçš„å½¢å¼å¯è‡ªç”±æ›¿æ¢ï¼›
Lua ä¼šè‡ªåŠ¨æ£€æµ‹æ–‡ä»¶æ ¼å¼åšç›¸åº”的处ç†
(å‚è§ load)。
Lua å…许多é‡èµ‹å€¼ã€‚ å› æ¤ï¼Œèµ‹å€¼çš„è¯æ³•定义是ç‰å·å·¦è¾¹æ”¾ä¸€ä¸ªå˜é‡åˆ—表, 而ç‰å·å³è¾¹æ”¾ä¸€ä¸ªè¡¨è¾¾å¼åˆ—表。 两边的列表ä¸çš„å…ƒç´ éƒ½ç”¨é€—å·é—´å¼€ï¼š
stat ::= varlist ‘=’ explist
varlist ::= var {‘,’ var}
explist ::= exp {‘,’ exp}
è¡¨è¾¾å¼æ”¾åœ¨ §3.4 ä¸è®¨è®ºã€‚
在作赋值æ“作之å‰ï¼Œ 那值列表会被 调整 为左边å˜é‡åˆ—表的个数。 如果值比需è¦çš„æ›´å¤šçš„è¯ï¼Œå¤šä½™çš„值就被扔掉。 如果值的数é‡ä¸å¤Ÿéœ€æ±‚, 将会按所需扩展若干个 nil。 如果表达å¼åˆ—表以一个函数调用结æŸï¼Œ 这个函数所返回的所有值都会在调整æ“作之å‰è¢«ç½®å…¥å€¼åˆ—è¡¨ä¸ ï¼ˆé™¤éžè¿™ä¸ªå‡½æ•°è°ƒç”¨è¢«ç”¨æ‹¬å·æ‹¬äº†èµ·æ¥ï¼›å‚è§ §3.4)。
赋值è¯å¥é¦–先让所有的表达å¼å®Œæˆè¿ç®—, 之åŽå†åšèµ‹å€¼æ“作。 å› æ¤ï¼Œä¸‹é¢è¿™æ®µä»£ç
i = 3
i, a[i] = i+1, 20
会把 a[3] 设置为 20,而ä¸ä¼šå½±å“到 a[4] 。
è¿™æ˜¯å› ä¸º a[i] ä¸çš„ i 在被赋值为 4 之å‰å°±è¢«è®¡ç®—出æ¥äº†ï¼ˆå½“时是 3 )。
简å•说 ï¼Œè¿™æ ·ä¸€è¡Œ
x, y = y, x
ä¼šäº¤æ¢ x å’Œ y 的值,
åŠ
x, y, z = y, z, x
ä¼šè½®æ¢ x,y,z 的值。
对全局å˜é‡ä»¥åŠè¡¨çš„域的赋值æ“作的å«ä¹‰å¯ä»¥é€šè¿‡å…ƒè¡¨æ¥æ”¹å˜ã€‚
对 t[i] = val è¿™æ ·çš„å˜é‡ç´¢å¼•赋值,
ç‰ä»·äºŽ settable_event(t,i,val)。
(关于函数 settable_event 的详细说明,å‚è§
§2.4。
这个函数并没有在 Lua ä¸å®šä¹‰å‡ºæ¥ï¼Œä¹Ÿä¸å¯ä»¥è¢«è°ƒç”¨ã€‚
这里我们列出æ¥ï¼Œä»…仅出于方便解释的目的。)
对于全局å˜é‡ x = val 的赋值ç‰ä»·äºŽ
_ENV.x = val
(å‚è§ §2.2)。
if, while, and repeat 这些控制结构符åˆé€šå¸¸çš„æ„ä¹‰ï¼Œè€Œä¸”ä¹Ÿæœ‰ç±»ä¼¼çš„è¯æ³•:
stat ::= while exp do block end
stat ::= repeat block until exp
stat ::= if exp then block {elseif exp then block} [else block] end
Lua 也有一个 for è¯å¥ï¼Œå®ƒæœ‰ä¸¤ç§å½¢å¼ (å‚è§ §3.3.5)。
控制结构ä¸çš„æ¡ä»¶è¡¨è¾¾å¼å¯ä»¥è¿”回任何值。 false 与 nil 两者都被认为是å‡ã€‚ 所有ä¸åŒäºŽ nil 与 false 的其它值都被认为是真 ï¼ˆç‰¹åˆ«éœ€è¦æ³¨æ„çš„æ˜¯ï¼Œæ•°å— 0 和空å—符串也被认为是真)。
在 repeat–until 循环ä¸ï¼Œ 内部è¯å¥å—的结æŸç‚¹ä¸æ˜¯åœ¨ until 这个关键å—处, 它还包括了其åŽçš„æ¡ä»¶è¡¨è¾¾å¼ã€‚ å› æ¤ï¼Œæ¡ä»¶è¡¨è¾¾å¼ä¸å¯ä»¥ä½¿ç”¨å¾ªçŽ¯å†…éƒ¨è¯å¥å—ä¸çš„定义的局部å˜é‡ã€‚
goto è¯å¥å°†ç¨‹åºçš„æŽ§åˆ¶ç‚¹è½¬ç§»åˆ°ä¸€ä¸ªæ ‡ç¾å¤„。 ç”±äºŽå¥æ³•ä¸Šçš„åŽŸå› ï¼Œ Lua é‡Œçš„æ ‡ç¾ä¹Ÿè¢«è®¤ä¸ºæ˜¯è¯å¥ï¼š
stat ::= goto Name stat ::= label label ::= ‘::’ Name ‘::’
除了在内嵌函数ä¸ï¼Œä»¥åŠåœ¨å†…嵌è¯å¥å—ä¸å®šä¹‰äº†åŒåæ ‡ç¾ï¼Œçš„æƒ…况外, æ ‡ç¾å¯¹äºŽå®ƒå®šä¹‰æ‰€åœ¨çš„æ•´ä¸ªè¯å¥å—å¯è§ã€‚ åªè¦ goto 没有进入一个新的局部å˜é‡çš„作用域,它å¯ä»¥è·³è½¬åˆ°ä»»æ„å¯è§æ ‡ç¾å¤„。
æ ‡ç¾å’Œæ²¡æœ‰å†…容的è¯å¥è¢«ç§°ä¸ºç©ºè¯å¥ï¼Œå®ƒä»¬ä¸åšä»»ä½•æ“作。
break 被用æ¥ç»“æŸ while〠repeatã€æˆ– for 循环, 它将跳到循环外接ç€ä¹‹åŽçš„è¯å¥è¿è¡Œï¼š
stat ::= break
break 跳出最内层的循环。
return 被用于从函数或是代ç å—(其实它就是一个函数) ä¸è¿”回值。 函数å¯ä»¥è¿”å›žä¸æ¢ä¸€ä¸ªå€¼ï¼Œæ‰€ä»¥ return çš„è¯æ³•为
stat ::= return [explist] [‘;’]
return åªèƒ½è¢«å†™åœ¨ä¸€ä¸ªè¯å¥å—的最åŽä¸€å¥ã€‚
å¦‚æžœä½ çœŸçš„éœ€è¦ä»Žè¯å¥å—çš„ä¸é—´ return,
ä½ å¯ä»¥ä½¿ç”¨æ˜¾å¼çš„定义一个内部è¯å¥å—,
一般写作 do return end。
å¯ä»¥è¿™æ ·å†™æ˜¯å› 为现在 return æˆäº†ï¼ˆå†…部)è¯å¥å—的最åŽä¸€å¥äº†ã€‚
for 有两ç§å½¢å¼ï¼šä¸€ç§æ˜¯æ•°å—å½¢å¼ï¼Œå¦ä¸€ç§æ˜¯é€šç”¨å½¢å¼ã€‚
æ•°å—å½¢å¼çš„ for 循环,通过一个数å¦è¿ç®—䏿–地è¿è¡Œå†…部的代ç å—。 䏋颿˜¯å®ƒçš„è¯æ³•:
stat ::= for Name ‘=’ exp ‘,’ exp [‘,’ exp] do block end
block 将把 name 作循环å˜é‡ã€‚ 从第一个 exp 开始起,直到第二个 exp 的值为æ¢ï¼Œ å…¶æ¥é•¿ä¸ºç¬¬ä¸‰ä¸ª exp 。 更确切的说,一个 for å¾ªçŽ¯çœ‹èµ·æ¥æ˜¯è¿™ä¸ªæ ·å
for v = e1, e2, e3 do block end
è¿™ç‰ä»·äºŽä»£ç :
do
local var, limit, step = tonumber(e1), tonumber(e2), tonumber(e3)
if not (var and limit and step) then error() end
var = var - step
while true do
var = var + step
if (step >= 0 and var > limit) or (step < 0 and var < limit) then
break
end
local v = var
block
end
end
注æ„下é¢è¿™å‡ 点:
var,limitï¼Œä»¥åŠ step
都是一些ä¸å¯è§çš„å˜é‡ã€‚
这里给它们起的åå—都仅仅用于解释方便。
v 是一个循环内部的局部å˜é‡ï¼›
å¦‚æžœä½ éœ€è¦åœ¨å¾ªçŽ¯ç»“æŸåŽä½¿ç”¨è¿™ä¸ªå€¼ï¼Œ
åœ¨é€€å‡ºå¾ªçŽ¯å‰æŠŠå®ƒèµ‹ç»™å¦ä¸€ä¸ªå˜é‡ã€‚
通用形å¼çš„ for 通过一个å«ä½œ è¿ä»£å™¨ 的函数工作。 æ¯æ¬¡è¿ä»£ï¼Œè¿ä»£å™¨å‡½æ•°éƒ½ä¼šè¢«è°ƒç”¨ä»¥äº§ç”Ÿä¸€ä¸ªæ–°çš„值, 当这个值为 nil æ—¶ï¼Œå¾ªçŽ¯åœæ¢ã€‚ 通用形å¼çš„ for å¾ªçŽ¯çš„è¯æ³•如下:
stat ::= for namelist in explist do block end
namelist ::= Name {‘,’ Name}
è¿™æ ·çš„ for è¯å¥
for var_1, ···, var_n in explist do block end
它ç‰ä»·äºŽè¿™æ ·ä¸€æ®µä»£ç :
do
local f, s, var = explist
while true do
local var_1, ···, var_n = f(s, var)
if var_1 == nil then break end
var = var_1
block
end
end
注æ„ä»¥ä¸‹å‡ ç‚¹ï¼š
explist åªä¼šè¢«è®¡ç®—一次。
它返回三个值, 一个 è¿ä»£å™¨ 函数,
一个 状æ€ï¼Œ
一个 è¿ä»£å™¨çš„åˆå§‹å€¼ã€‚
f, s,与 var
都是ä¸å¯è§çš„å˜é‡ã€‚
这里给它们起的åå—éƒ½åªæ˜¯ä¸ºäº†è§£è¯´æ–¹ä¾¿ã€‚
var_i 对于循环æ¥è¯´æ˜¯ä¸€ä¸ªå±€éƒ¨å˜é‡ï¼›
ä½ ä¸å¯ä»¥åœ¨ for 循环结æŸåŽç»§ç»ä½¿ç”¨ã€‚
å¦‚æžœä½ éœ€è¦ä¿ç•™è¿™äº›å€¼ï¼Œé‚£ä¹ˆå°±åœ¨å¾ªçŽ¯è·³å‡ºæˆ–ç»“æŸå‰èµ‹å€¼åˆ°åˆ«çš„å˜é‡é‡ŒåŽ»ã€‚
为了å…许使用函数的副作用, 函数调用å¯ä»¥è¢«ä½œä¸ºä¸€ä¸ªè¯å¥æ‰§è¡Œï¼š
stat ::= functioncall
åœ¨è¿™ç§æƒ…况下,所有的返回值都被èˆå¼ƒã€‚ 函数调用在 §3.4.10 ä¸è§£é‡Šã€‚
局部å˜é‡å¯ä»¥åœ¨è¯å¥å—ä¸ä»»ä½•地方声明。 声明å¯ä»¥åŒ…å«ä¸€ä¸ªåˆå§‹åŒ–赋值æ“作:
stat ::= local namelist [‘=’ explist]
如果有åˆå§‹åŒ–值的è¯ï¼Œåˆå§‹åŒ–赋值æ“ä½œçš„è¯æ³•和赋值æ“作一致 (å‚è§ §3.3.3 )。 若没有åˆå§‹åŒ–值,所有的å˜é‡éƒ½è¢«åˆå§‹åŒ–为 nil。
一个代ç å—åŒæ—¶ä¹Ÿæ˜¯ä¸€ä¸ªè¯å¥å—(å‚è§ §3.3.2), 所以局部å˜é‡å¯ä»¥æ”¾åœ¨ä»£ç å—ä¸é‚£äº›æ˜¾å¼æ³¨æ˜Žçš„è¯å¥å—之外。
局部å˜é‡çš„å¯è§æ€§è§„则在 §3.5 ä¸è§£é‡Šã€‚
Lua 䏿œ‰è¿™äº›åŸºæœ¬è¡¨è¾¾å¼ï¼š
exp ::= prefixexp exp ::= nil | false | true exp ::= Numeral 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 ä¸è§£é‡Šã€‚
å¯å˜å‚数的表达å¼å†™ä½œä¸‰ä¸ªç‚¹ï¼ˆ'...'),
它åªèƒ½åœ¨æœ‰å¯å˜å‚数的函数ä¸ç›´æŽ¥ä½¿ç”¨ï¼›è¿™äº›åœ¨ §3.4.11 ä¸è§£é‡Šã€‚
二元æ“ä½œç¬¦åŒ…å«æœ‰æ•°å¦è¿ç®—æ“作符(å‚è§ §3.4.1), 使“作符(å‚è§ §3.4.2), 比较æ“作符(å‚è§ §3.4.4), 逻辑æ“作符(å‚è§ §3.4.5), 以åŠè¿žæŽ¥æ“作符(å‚è§ §3.4.6)。 一元æ“作符包括负å·ï¼ˆå‚è§ §3.4.1), 按ä½éžï¼ˆå‚è§ §3.4.2), 逻辑éžï¼ˆå‚è§ §3.4.5), å’Œå–长度æ“作符(å‚è§ §3.4.7)。
函数调用和å¯å˜å‚数表达å¼éƒ½å¯ä»¥æ”¾åœ¨å¤šé‡è¿”回值ä¸ã€‚ 如果函数调用被当作一æ¡è¯å¥ï¼ˆå‚è§ §3.3.6), å…¶è¿”å›žå€¼åˆ—è¡¨è¢«è°ƒæ•´ä¸ºé›¶ä¸ªå…ƒç´ ï¼Œå³æŠ›å¼ƒæ‰€æœ‰çš„è¿”å›žå€¼ã€‚ 如果表达å¼è¢«ç”¨äºŽè¡¨è¾¾å¼åˆ—表的最åŽï¼ˆæˆ–æ˜¯å”¯ä¸€çš„ï¼‰ä¸€ä¸ªå…ƒç´ ï¼Œ 那么ä¸ä¼šåšä»»ä½•调整(除éžè¡¨è¾¾å¼è¢«æ‹¬å·æ‹¬èµ·æ¥ï¼‰ã€‚ 在其它情况下, Lua éƒ½ä¼šæŠŠç»“æžœè°ƒæ•´ä¸ºä¸€ä¸ªå…ƒç´ ç½®å…¥è¡¨è¾¾å¼åˆ—表ä¸ï¼Œ å³ä¿ç•™ç¬¬ä¸€ä¸ªç»“果而忽略之åŽçš„æ‰€æœ‰å€¼ï¼Œæˆ–是在没有结果时, è¡¥å•个 nil。
这里有一些例å:
f() -- 调整为 0 个结果
g(f(), x) -- f() 会被调整为一个结果
g(x, f()) -- g 收到 x ä»¥åŠ f() 返回的所有结果
a,b,c = f(), x -- f() 被调整为 1 个结果 (c 收到 nil)
a,b = ... -- a 收到å¯å˜å‚æ•°åˆ—è¡¨çš„ç¬¬ä¸€ä¸ªå‚æ•°ï¼Œ
-- b æ”¶åˆ°ç¬¬äºŒä¸ªå‚æ•°ï¼ˆå¦‚æžœå¯å˜å‚数列表ä¸
-- æ²¡æœ‰å®žé™…çš„å‚æ•°ï¼Œa å’Œ b 都会收到 nil)
a,b,c = x, f() -- f() 被调整为 2 个结果
a,b,c = f() -- f() 被调整为 3 个结果
return f() -- 返回 f() 的所有返回结果
return ... -- 返回从å¯å˜å‚æ•°åˆ—è¡¨ä¸æŽ¥æ”¶åˆ°çš„æ‰€æœ‰å‚æ•°parameters
return x,y,f() -- 返回 x, y, ä»¥åŠ f() 的所有返回值
{f()} -- 用 f() 的所有返回值创建一个列表
{...} -- 用å¯å˜å‚æ•°ä¸çš„æ‰€æœ‰å€¼åˆ›å»ºä¸€ä¸ªåˆ—表
{f(), nil} -- f() 被调整为一个结果
è¢«æ‹¬å·æ‹¬èµ·æ¥çš„è¡¨è¾¾å¼æ°¸è¿œè¢«å½“作一个值。
所以,
(f(x,y,z)) å³ä½¿ f 返回多个值,
è¿™ä¸ªè¡¨è¾¾å¼æ°¸è¿œæ˜¯ä¸€ä¸ªå•一值。
((f(x,y,z)) 的值是 f 返回的第一个值。
如果 f ä¸è¿”回值的è¯ï¼Œé‚£ä¹ˆå®ƒçš„值就是 nil 。)
Lua 支æŒä¸‹åˆ—æ•°å¦è¿ç®—æ“作符:
+: åŠ æ³•-: 凿³•*: 乘法/: 浮点除法//: å‘䏋喿•´é™¤æ³•%: å–æ¨¡^: 乘方-: å–负除了乘方和浮点除法è¿ç®—, æ•°å¦è¿ç®—按如下方å¼å·¥ä½œï¼š 如果两个æ“作数都是整数, 该æ“ä½œä»¥æ•´æ•°æ–¹å¼æ“作且结果也将是一个整数。 å¦åˆ™ï¼Œå½“两个æ“ä½œæ•°éƒ½æ˜¯æ•°å—æˆ–å¯ä»¥è¢«è½¬æ¢ä¸ºæ•°å—çš„å—符串 (å‚è§ §3.4.3)时, æ“ä½œæ•°ä¼šè¢«è½¬æ¢æˆä¸¤ä¸ªæµ®ç‚¹æ•°ï¼Œ æ“作按通常的浮点规则(一般éµå¾ª IEEE 754 æ ‡å‡†ï¼‰ æ¥è¿›è¡Œï¼Œç»“果也是一个浮点数。
乘方和浮点除法 (/)
总是把æ“ä½œæ•°è½¬æ¢æˆæµ®ç‚¹æ•°è¿›è¡Œï¼Œå…¶ç»“果总是浮点数。
乘方使用 ISO C 函数 pow,
å› æ¤å®ƒä¹Ÿå¯ä»¥æŽ¥å—éžæ•´æ•°çš„æŒ‡æ•°ã€‚
å‘䏋喿•´çš„除法 (//)
指åšä¸€æ¬¡é™¤æ³•,并将商圆整到é è¿‘è´Ÿæ— ç©·çš„ä¸€ä¾§ï¼Œ
å³å¯¹æ“作数åšé™¤æ³•åŽå– floor 。
å–æ¨¡è¢«å®šä¹‰æˆé™¤æ³•的余数,其商被圆整到é è¿‘è´Ÿæ— ç©·çš„ä¸€ä¾§ï¼ˆå‘䏋喿•´çš„除法)。
对于整数数å¦è¿ç®—的溢出问题, 这些æ“作采å–çš„ç–略是按通常éµå¾ªçš„以 2 为补ç 的数å¦è¿ç®—çš„ 环绕 规则。 (æ¢å¥è¯è¯´ï¼Œå®ƒä»¬è¿”回其è¿ç®—的数å¦ç»“果对 264 å–æ¨¡åŽçš„æ•°å—。)
Lua 支æŒä¸‹åˆ—使“作符:
&: 按ä½ä¸Ž|: æŒ‰ä½æˆ–~: 按ä½å¼‚或>>: å³ç§»<<: 左移~: 按ä½éžæ‰€æœ‰çš„使“作都将æ“作数先转æ¢ä¸ºæ•´æ•° (å‚è§ §3.4.3), ç„¶åŽæŒ‰ä½æ“作,其结果是一个整数。
对于å³ç§»å’Œå·¦ç§»ï¼Œå‡ç”¨é›¶æ¥å¡«è¡¥ç©ºä½ã€‚ ç§»åŠ¨çš„ä½æ•°è‹¥ä¸ºè´Ÿï¼Œåˆ™å‘åæ–¹å‘ä½ç§»ï¼› è‹¥ç§»åŠ¨çš„ä½æ•°çš„ç»å¯¹å€¼å¤§äºŽç‰äºŽ æ•´æ•°æœ¬èº«çš„ä½æ•°ï¼Œå…¶ç»“果为零 (所有ä½éƒ½è¢«ç§»å‡ºï¼‰ã€‚
Lua 对一些类型和值的内部表示会在è¿è¡Œæ—¶åšä¸€äº›æ•°å¦è½¬æ¢ã€‚ 使“作总是将浮点æ“ä½œæ•°è½¬æ¢æˆæ•´æ•°ã€‚ 乘方和浮点除法总是将整数转æ¢ä¸ºæµ®ç‚¹æ•°ã€‚ å…¶å®ƒæ•°å¦æ“ä½œè‹¥é’ˆå¯¹æ··åˆæ“作数 (整数和浮点数)将把整数转æ¢ä¸ºæµ®ç‚¹æ•°ï¼› 这一点被称为 通常规则。 C API åŒæ ·ä¼šæŒ‰éœ€æŠŠæ•´æ•°è½¬æ¢ä¸ºæµ®ç‚¹æ•°ä»¥åŠ æŠŠæµ®ç‚¹æ•°è½¬æ¢ä¸ºæ•´æ•°ã€‚ æ¤å¤–,å—符串连接æ“作除了å—符串,也å¯ä»¥æŽ¥å—æ•°å—ä½œä¸ºå‚æ•°ã€‚
当æ“ä½œéœ€è¦æ•°å—时,Lua 还会把å—符串转æ¢ä¸ºæ•°å—。
当把一个整数转æ¢ä¸ºæµ®ç‚¹æ•°æ—¶ï¼Œ 若整数值æ°å¥½å¯ä»¥è¡¨ç¤ºä¸ºä¸€ä¸ªæµ®ç‚¹æ•°ï¼Œé‚£å°±å–那个浮点数。 å¦åˆ™ï¼Œè½¬æ¢ä¼šå–最接近的较大值或较å°å€¼æ¥è¡¨ç¤ºè¿™ä¸ªæ•°ã€‚ è¿™ç§è½¬æ¢æ˜¯ä¸ä¼šå¤±è´¥çš„。
将浮点数转为整数的过程会检查 浮点数能å¦è¢«å‡†ç¡®çš„表达为一个整数 (å³ï¼Œæµ®ç‚¹æ•°æ˜¯ä¸€ä¸ªæ•´æ•°å€¼ä¸”在整数å¯ä»¥è¡¨è¾¾çš„区间)。 如果å¯ä»¥ï¼Œç»“果就是那个数,å¦åˆ™è½¬æ¢å¤±è´¥ã€‚
从å—符串到数å—的转æ¢è¿‡ç¨‹éµå¾ªä»¥ä¸‹æµç¨‹ï¼š 首先,éµå¾ªæŒ‰ Lua è¯æ³•分æžå™¨çš„规则分æžè¯æ³•æ¥è½¬æ¢ä¸ºå¯¹åº”çš„ 整数或浮点数。 (å—符串å¯ä»¥æœ‰å‰ç½®æˆ–åŽç½®çš„ç©ºæ ¼ä»¥åŠä¸€ä¸ªç¬¦å·ã€‚) ç„¶åŽï¼Œç»“果数å—冿Œ‰å‰è¿°è§„则转æ¢ä¸ºæ‰€éœ€è¦çš„类型(浮点或整数)。
从数å—转æ¢ä¸ºå—ç¬¦ä¸²ä½¿ç”¨éžæŒ‡å®šçš„人å¯è¯»çš„æ ¼å¼ã€‚
若想完全控制数å—到å—符串的转æ¢è¿‡ç¨‹ï¼Œ
å¯ä»¥ä½¿ç”¨å—符串库ä¸çš„ format 函数
(å‚è§ string.format)。
Lua 支æŒä¸‹åˆ—比较æ“作符:
==: ç‰äºŽ~=: ä¸ç‰äºŽ<: å°äºŽ>: 大于<=: å°äºŽç‰äºŽ>=: 大于ç‰äºŽè¿™äº›æ“ä½œçš„ç»“æžœä¸æ˜¯ false 就是 true。
ç‰äºŽæ“作 (==)先比较æ“作数的类型。
如果类型ä¸åŒï¼Œç»“果就是 false。
å¦åˆ™ï¼Œç»§ç»æ¯”较值。
å—ç¬¦ä¸²æŒ‰ä¸€èˆ¬çš„æ–¹å¼æ¯”较。
æ•°å—éµå¾ªäºŒå…ƒæ“作的规则:
如果两个æ“作数都是整数,
它们按整数比较;
å¦åˆ™ï¼Œå®ƒä»¬å…ˆè½¬æ¢ä¸ºæµ®ç‚¹æ•°ï¼Œç„¶åŽå†åšæ¯”è¾ƒã€‚
表,用户数æ®ï¼Œä»¥åŠçº¿ç¨‹éƒ½æŒ‰å¼•用比较: åªæœ‰ä¸¤è€…引用åŒä¸€ä¸ªå¯¹è±¡æ—¶æ‰è®¤ä¸ºå®ƒä»¬ç›¸ç‰ã€‚ æ¯æ¬¡ä½ åˆ›å»ºä¸€ä¸ªæ–°å¯¹è±¡ï¼ˆä¸€å¼ è¡¨ï¼Œä¸€ä¸ªç”¨æˆ·æ•°æ®ï¼Œæˆ–一个线程), 新对象都一定和已有且å˜åœ¨çš„对象ä¸åŒã€‚ 相åŒå¼•用的é—包一定相ç‰ã€‚ 有任何å¯å¯Ÿè§‰çš„差异(ä¸åŒçš„行为,ä¸åŒçš„定义)一定ä¸ç‰ã€‚
ä½ å¯ä»¥é€šè¿‡ä½¿ç”¨ "eq" 元方法(å‚è§ §2.4) æ¥æ”¹å˜ Lua æ¯”è¾ƒè¡¨å’Œç”¨æˆ·æ•°æ®æ—¶çš„æ–¹å¼ã€‚
ç‰äºŽæ“作ä¸ä¼šå°†å—符串转æ¢ä¸ºæ•°å—,å之亦然。
å³ï¼Œ"0"==0 结果为 false,
且 t[0] 与 t["0"] 指代ç€è¡¨ä¸çš„ä¸åŒé¡¹ã€‚
~= æ“作完全ç‰ä»·äºŽ (==) æ“作的å值。
大尿¯”较æ“作以以下方å¼è¿›è¡Œã€‚
å¦‚æžœå‚æ•°éƒ½æ˜¯æ•°å—,
它们按二元æ“作的常规进行。
å¦åˆ™ï¼Œå¦‚æžœä¸¤ä¸ªå‚æ•°éƒ½æ˜¯å—符串,
它们的值按当å‰çš„åŒºåŸŸè®¾ç½®æ¥æ¯”较。
å†åˆ™ï¼ŒLua 就试ç€è°ƒç”¨ "lt" 或是 "le" 元方法
(å‚è§ §2.4)。
a > b 的比较被转译为 b < a,
a >= b 被转译为 b <= a。
Lua ä¸çš„逻辑æ“作符有 and, orï¼Œä»¥åŠ not。 和控制结构(å‚è§ §3.3.4ï¼‰ä¸€æ ·ï¼Œ 所有的逻辑æ“作符把 false å’Œ nil 都作为å‡ï¼Œ 而其它的一切都当作真。
å–åæ“ä½œ not 总是返回 false 或 true ä¸çš„一个。 与æ“作符 and åœ¨ç¬¬ä¸€ä¸ªå‚æ•°ä¸º false 或 nil æ—¶ è¿”å›žè¿™ç¬¬ä¸€ä¸ªå‚æ•°ï¼› å¦åˆ™ï¼Œand è¿”å›žç¬¬äºŒä¸ªå‚æ•°ã€‚ 或æ“作符 or åœ¨ç¬¬ä¸€ä¸ªå‚æ•°ä¸ä¸º nil 也ä¸ä¸º false 时, è¿”å›žè¿™ç¬¬ä¸€ä¸ªå‚æ•°ï¼Œå¦åˆ™è¿”å›žç¬¬äºŒä¸ªå‚æ•°ã€‚ 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 ä¸å—符串的连接æ“作符写作两个点('..')。
如果两个æ“作数都是å—符串或都是数å—,
连接æ“作将以 §3.4.3 ä¸æåˆ°çš„è§„åˆ™æŠŠå…¶è½¬æ¢ä¸ºå—符串。
å¦åˆ™ï¼Œä¼šè°ƒç”¨å…ƒæ–¹æ³• __concat (å‚è§ §2.4)。
å–长度æ“作符写作一元å‰ç½®ç¬¦ #。
å—符串的长度是它的å—节数(就是以一个å—符一个å—节计算的å—符串长度)。
程åºå¯ä»¥é€šè¿‡ __len 元方法(å‚è§ §2.4)
æ¥ä¿®æ”¹å¯¹å—符串类型外的任何值的å–长度æ“作行为。
如果 __len 元方法没有给出,
表 t 的长度åªåœ¨è¡¨æ˜¯ä¸€ä¸ª åºåˆ— 时有定义。
åºåˆ—æŒ‡è¡¨çš„æ£æ•°é”®é›†ç‰äºŽ {1..n} ,
å…¶ä¸ n 是一个éžè´Ÿæ•´æ•°ã€‚
åœ¨è¿™ç§æƒ…况下,n 是表的长度。
注æ„è¿™æ ·çš„è¡¨
{10, 20, nil, 40}
䏿˜¯ä¸€ä¸ªåºåˆ—ï¼Œå› ä¸ºå®ƒæœ‰é”® 4
å´æ²¡æœ‰é”® 3。
ï¼ˆå› æ¤ï¼Œè¯¥è¡¨çš„æ£æ•´æ•°é”®é›†ä¸ç‰äºŽ {1..n} 集åˆï¼Œæ•…而就ä¸å˜åœ¨ n。)
注æ„ï¼Œä¸€å¼ è¡¨æ˜¯å¦æ˜¯ä¸€ä¸ªåºåˆ—å’Œå®ƒçš„éžæ•°å—é”®æ— å…³ã€‚
Lua 䏿“作符的优先级写在下表ä¸ï¼Œä»Žä½Žåˆ°é«˜ä¼˜å…ˆçº§æŽ’åºï¼š
or
and
< > <= >= ~= ==
|
~
&
<< >>
..
+ -
* / // %
unary operators (not # - ~)
^
通常,
ä½ å¯ä»¥ç”¨æ‹¬å·æ¥æ”¹å˜è¿ç®—次åºã€‚
连接æ“作符 ('..') 和乘方æ“作 ('^')
是从å³è‡³å·¦çš„。
其它所有的æ“作都是从左至å³ã€‚
è¡¨æž„é€ åæ˜¯ä¸€ä¸ªæž„é€ è¡¨çš„è¡¨è¾¾å¼ã€‚ æ¯æ¬¡æž„é€ åè¢«æ‰§è¡Œï¼Œéƒ½ä¼šæž„é€ å‡ºä¸€å¼ æ–°çš„è¡¨ã€‚ æž„é€ åå¯ä»¥è¢«ç”¨æ¥æž„é€ ä¸€å¼ ç©ºè¡¨ï¼Œ 也å¯ä»¥ç”¨æ¥æž„é€ ä¸€å¼ è¡¨å¹¶åˆå§‹åŒ–å…¶ä¸çš„一些域。 ä¸€èˆ¬çš„æž„é€ åçš„è¯æ³•如下
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 -- t["x"] = 1
t[3] = f(x) -- 3rd exp
t[30] = 23
t[4] = 45 -- 4th exp
a = t
end
æž„é€ åä¸èµ‹å€¼çš„æ¬¡åºæœªå®šä¹‰ã€‚ (次åºé—®é¢˜åªä¼šå¯¹é‚£äº›é”®é‡å¤æ—¶çš„æƒ…况有影å“。)
如果表å•䏿œ€åŽä¸€ä¸ªåŸŸçš„形弿˜¯ exp ,
è€Œä¸”å…¶è¡¨è¾¾å¼æ˜¯ä¸€ä¸ªå‡½æ•°è°ƒç”¨æˆ–者是一个å¯å˜å‚数,
é‚£ä¹ˆè¿™ä¸ªè¡¨è¾¾å¼æ‰€æœ‰çš„è¿”å›žå€¼å°†ä¾æ¬¡è¿›å…¥åˆ—表
(å‚è§ §3.4.10)。
åˆå§‹åŒ–域表å¯ä»¥åœ¨æœ€åŽå¤šä¸€ä¸ªåˆ†å‰²ç¬¦ï¼Œ è¿™æ ·è®¾è®¡å¯ä»¥æ–¹ä¾¿ç”±æœºå™¨ç”Ÿæˆä»£ç 。
Lua ä¸çš„å‡½æ•°è°ƒç”¨çš„è¯æ³•如下:
functioncall ::= prefixexp args
函数调用时, 第一æ¥ï¼Œprefixexp å’Œ args 先被求值。 如果 prefixexp 的值的类型是 function, é‚£ä¹ˆè¿™ä¸ªå‡½æ•°å°±è¢«ç”¨ç»™å‡ºçš„å‚æ•°è°ƒç”¨ã€‚ å¦åˆ™ prefixexp 的元方法 "call" 就被调用, ç¬¬ä¸€ä¸ªå‚æ•°æ˜¯ prefixexp 的值, 接下æ¥çš„æ˜¯åŽŸæ¥çš„è°ƒç”¨å‚æ•° (å‚è§ §2.4)。
è¿™æ ·çš„å½¢å¼
functioncall ::= prefixexp ‘:’ Name args
å¯ä»¥ç”¨æ¥è°ƒç”¨ "方法"。
这是 Lua 支æŒçš„一ç§è¯æ³•糖。
åƒ 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')ï¼›
æ¤æ—¶çš„傿•°åˆ—表是一个å•独的å—符串。
return functioncall
è¿™æ ·çš„è°ƒç”¨å½¢å¼å°†è§¦å‘一次 尾调用。
Lua 实现了 完全尾调用(或称为 完全尾递归):
在尾调用ä¸ï¼Œ 被调用的函数é‡ç”¨è°ƒç”¨å®ƒçš„å‡½æ•°çš„å †æ ˆé¡¹ã€‚
å› æ¤ï¼Œå¯¹äºŽç¨‹åºæ‰§è¡Œçš„嵌套尾调用的层数是没有é™åˆ¶çš„。
ç„¶è€Œï¼Œå°¾è°ƒç”¨å°†åˆ é™¤è°ƒç”¨å®ƒçš„å‡½æ•°çš„ä»»ä½•è°ƒè¯•ä¿¡æ¯ã€‚
注æ„,尾调用åªå‘ç”Ÿåœ¨ç‰¹å®šçš„è¯æ³•下,
仅当 return åªæœ‰å•ä¸€å‡½æ•°è°ƒç”¨ä½œä¸ºå‚æ•°æ—¶æ‰å‘生尾调用;
è¿™ç§è¯æ³•使得调用函数的所有结果å¯ä»¥å®Œæ•´åœ°è¿”回。
å› æ¤ï¼Œä¸‹é¢è¿™äº›ä¾‹åéƒ½ä¸æ˜¯å°¾è°ƒç”¨ï¼š
return (f(x)) -- 返回值被调整为一个
return 2 * f(x)
return x, f(x) -- è¿½åŠ è‹¥å¹²è¿”å›žå€¼
f(x); return -- 返回值全部被èˆå¼ƒ
return x or f(x) -- 返回值被调整为一个
å‡½æ•°å®šä¹‰çš„è¯æ³•如下:
functiondef ::= function funcbody funcbody ::= ‘(’ [parlist] ‘)’ 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 () body end
è€Œä¸æ˜¯
local f = function () body end
(这个差别åªåœ¨å‡½æ•°ä½“内需è¦å¼•用 f æ—¶æ‰æœ‰ã€‚)
ä¸€ä¸ªå‡½æ•°å®šä¹‰æ˜¯ä¸€ä¸ªå¯æ‰§è¡Œçš„表达å¼ï¼Œ 执行结果是一个类型为 function 的值。 当 Lua 预编译一个代ç å—æ—¶ï¼Œ 代ç å—作为一个函数,整个函数体也就被预编译了。 é‚£ä¹ˆï¼Œæ— è®ºä½•æ—¶ Lua 执行了函数定义, 这个函数本身就进行了 实例化(或者说是 å…³é—了)。 这个函数的实例(或者说是 é—包)是表达å¼çš„æœ€ç»ˆå€¼ã€‚
å½¢å‚被看作是一些局部å˜é‡ï¼Œ 它们将由实å‚的值æ¥åˆå§‹åŒ–:
parlist ::= namelist [‘,’ ‘...’] | ‘...’
当一个函数被调用,
如果函数并éžä¸€ä¸ª å¯å˜å‚数函数,
å³åœ¨å½¢å‚列表的末尾注明三个点 ('...'),
那么实å‚列表就会被调整到形å‚列表的长度。
å˜é•¿å‚数函数ä¸ä¼šè°ƒæ•´å®žå‚列表;
å–而代之的是,它将把所有é¢å¤–çš„å‚æ•°æ”¾åœ¨ä¸€èµ·é€šè¿‡
å˜é•¿å‚数表达å¼ä¼ 递给函数,
å…¶å†™æ³•ä¾æ—§æ˜¯ä¸‰ä¸ªç‚¹ã€‚
这个表达å¼çš„值是一串实å‚值的列表,
看起æ¥å°±è·Ÿä¸€ä¸ªå¯ä»¥è¿”å›žå¤šä¸ªç»“æžœçš„å‡½æ•°ä¸€æ ·ã€‚
如果一个å˜é•¿å‚æ•°è¡¨è¾¾å¼æ”¾åœ¨å¦ä¸€ä¸ªè¡¨è¾¾å¼ä¸ä½¿ç”¨ï¼Œ
或是放在å¦ä¸€ä¸²è¡¨è¾¾å¼çš„ä¸é—´ï¼Œ
那么它的返回值就会被调整为å•个值。
è‹¥è¿™ä¸ªè¡¨è¾¾å¼æ”¾åœ¨äº†ä¸€ç³»åˆ—表达å¼çš„æœ€åŽä¸€ä¸ªï¼Œ
å°±ä¸ä¼šåšè°ƒæ•´äº†
(除éžè¿™æœ€åŽä¸€ä¸ªå‚数被括å·ç»™æ‹¬äº†èµ·æ¥ï¼‰ã€‚
我们先åšå¦‚下定义,然åŽå†æ¥çœ‹ä¸€ä¸ªä¾‹å:
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
结果由 return æ¥è¿”回(å‚è§ §3.3.4)。 å¦‚æžœæ‰§è¡Œåˆ°å‡½æ•°æœ«å°¾ä¾æ—§æ²¡æœ‰é‡åˆ°ä»»ä½• return è¯å¥ï¼Œ 函数就ä¸ä¼šè¿”回任何结果。
关于函数å¯è¿”回值的数é‡é™åˆ¶å’Œç³»ç»Ÿæœ‰å…³ã€‚ 这个é™åˆ¶ä¸€å®šå¤§äºŽ 1000 。
å†’å· è¯æ³•å¯ä»¥ç”¨æ¥å®šä¹‰ 方法,
就是说,函数å¯ä»¥æœ‰ä¸€ä¸ªéšå¼çš„å½¢å‚ self。
å› æ¤ï¼Œå¦‚下è¯å¥
function t.a.b.c:f (params) body end
æ˜¯è¿™æ ·ä¸€ç§å†™æ³•çš„è¯æ³•ç³–
t.a.b.c.f = function (self, params) body end
Lua è¯è¨€æœ‰è¯æ³•作用范围。 å˜é‡çš„作用范围开始于声明它们之åŽçš„第一个è¯å¥æ®µï¼Œ 结æŸäºŽåŒ…å«è¿™ä¸ªå£°æ˜Žçš„æœ€å†…层è¯å¥å—的最åŽä¸€ä¸ªéžç©ºè¯å¥ã€‚ 看下é¢è¿™äº›ä¾‹å:
x = 10 -- 全局å˜é‡
do -- æ–°çš„è¯å¥å—
local x = x -- 新的一个 'x', 它的值现在是 10
print(x) --> 10
x = x+1
do -- å¦ä¸€ä¸ªè¯å¥å—
local x = x+1 -- åˆä¸€ä¸ª 'x'
print(x) --> 12
end
print(x) --> 11
end
print(x) --> 10 (å–到的是全局的那一个)
注æ„这里,类似 local x = x è¿™æ ·çš„å£°æ˜Žï¼Œ
æ–°çš„ x æ£åœ¨è¢«å£°æ˜Žï¼Œä½†æ˜¯è¿˜æ²¡æœ‰è¿›å…¥å®ƒçš„作用范围,
所以第二个 x 指å‘的是外é¢ä¸€å±‚çš„å˜é‡ã€‚
å› ä¸ºæœ‰è¿™æ ·ä¸€ä¸ªè¯æ³•作用范围的规则, 局部å˜é‡å¯ä»¥è¢«åœ¨å®ƒçš„作用范围内定义的函数自由使用。 当一个局部å˜é‡è¢«å†…层的函数ä¸ä½¿ç”¨çš„æ—¶å€™ï¼Œ 它被内层函数称作 上值,或是 外部局部å˜é‡ã€‚
注æ„ï¼Œæ¯æ¬¡æ‰§è¡Œåˆ°ä¸€ä¸ª local è¯å¥éƒ½ä¼šå®šä¹‰å‡ºä¸€ä¸ªæ–°çš„局部å˜é‡ã€‚ çœ‹çœ‹è¿™æ ·ä¸€ä¸ªä¾‹å:
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。
这个部分æè¿°äº† Lua çš„ C API ,
也就是宿主程åºè·Ÿ Lua 通讯用的一组 C 函数。
所有的 API 函数按相关的类型以åŠå¸¸é‡éƒ½å£°æ˜Žåœ¨å¤´æ–‡ä»¶
lua.h ä¸ã€‚
虽然我们说的是“函数â€ï¼Œ 但一部分简å•çš„ API 是以å®çš„å½¢å¼æä¾›çš„ã€‚ 除éžå¦æœ‰è¯´æ˜Žï¼Œ 所有的这些å®éƒ½åªä½¿ç”¨å®ƒä»¬çš„傿•°ä¸€æ¬¡ ï¼ˆé™¤äº†ç¬¬ä¸€ä¸ªå‚æ•°ï¼Œé‚£ä¸€å®šæ˜¯ Lua 状æ€ï¼‰ï¼Œ å› æ¤ä½ ä¸éœ€æ‹…心这些å®çš„展开会引起一些副作用。
C åº“ä¸æ‰€æœ‰çš„ Lua API 函数都ä¸åŽ»æ£€æŸ¥å‚æ•°æ˜¯å¦ç›¸å®¹åŠæœ‰æ•ˆã€‚
ç„¶è€Œï¼Œä½ å¯ä»¥åœ¨ç¼–译 Lua æ—¶åŠ ä¸Šæ‰“å¼€ä¸€ä¸ªå®å¼€å…³
LUA_USE_APICHECK
æ¥æ”¹å˜è¿™ä¸ªè¡Œä¸ºã€‚
Lua 使用一个 è™šæ‹Ÿæ ˆ æ¥å’Œ C äº’ä¼ å€¼ã€‚ æ ˆä¸Šçš„çš„æ¯ä¸ªå…ƒç´ 都是一个 Lua 值 (nil,数å—,å—符串,ç‰ç‰ï¼‰ã€‚
æ— è®ºä½•æ—¶ Lua 调用 Cï¼Œè¢«è°ƒç”¨çš„å‡½æ•°éƒ½å¾—åˆ°ä¸€ä¸ªæ–°çš„æ ˆï¼Œ
è¿™ä¸ªæ ˆç‹¬ç«‹äºŽ C å‡½æ•°æœ¬èº«çš„æ ˆï¼Œä¹Ÿç‹¬ç«‹äºŽä¹‹å‰çš„ Lua æ ˆã€‚
它里é¢åŒ…å«äº† Lua ä¼ é€’ç»™ C å‡½æ•°çš„æ‰€æœ‰å‚æ•°ï¼Œ
而 C 函数则把è¦è¿”å›žçš„ç»“æžœæ”¾å…¥è¿™ä¸ªæ ˆä»¥è¿”å›žç»™è°ƒç”¨è€…
(å‚è§ lua_CFunction)。
方便起è§ï¼Œ æ‰€æœ‰é’ˆå¯¹æ ˆçš„ API 查询æ“作都ä¸ä¸¥æ ¼éµå¾ªæ ˆçš„æ“ä½œè§„åˆ™ã€‚ 而是å¯ä»¥ç”¨ä¸€ä¸ª 索引 æ¥æŒ‡å‘æ ˆä¸Šçš„ä»»ä½•å…ƒç´ ï¼š æ£çš„ç´¢å¼•æŒ‡çš„æ˜¯æ ˆä¸Šçš„ç»å¯¹ä½ç½®ï¼ˆä»Ž1开始); è´Ÿçš„ç´¢å¼•åˆ™æŒ‡ä»Žæ ˆé¡¶å¼€å§‹çš„åç§»é‡ã€‚ 展开æ¥è¯´ï¼Œå¦‚æžœå †æ ˆæœ‰ n ä¸ªå…ƒç´ ï¼Œ 那么索引 1 è¡¨ç¤ºç¬¬ä¸€ä¸ªå…ƒç´ ï¼ˆä¹Ÿå°±æ˜¯æœ€å…ˆè¢«åŽ‹æ ˆçš„å…ƒç´ ï¼‰ 而索引 n 则指最åŽä¸€ä¸ªå…ƒç´ ï¼› 索引 -1 也是指最åŽä¸€ä¸ªå…ƒç´ ï¼ˆå³æ ˆé¡¶çš„å…ƒç´ ï¼‰ï¼Œ 索引 -n æ˜¯æŒ‡ç¬¬ä¸€ä¸ªå…ƒç´ ã€‚
å½“ä½ ä½¿ç”¨ Lua API 时,
就有责任ä¿è¯åšæ°å½“的调用。
ç‰¹åˆ«éœ€è¦æ³¨æ„的是,
ä½ æœ‰è´£ä»»æŽ§åˆ¶ä¸è¦å †æ ˆæº¢å‡ºã€‚
ä½ å¯ä»¥ä½¿ç”¨ lua_checkstack
è¿™ä¸ªå‡½æ•°æ¥æ‰©å¤§å¯ç”¨å †æ ˆçš„尺寸。
æ— è®ºä½•æ—¶ Lua 调用 C ,
它都åªä¿è¯è‡³å°‘有
LUA_MINSTACK
è¿™ä¹ˆå¤šçš„å †æ ˆç©ºé—´å¯ä»¥ä½¿ç”¨ã€‚
LUA_MINSTACK 一般被定义为 20 ,
å› æ¤ï¼Œåªè¦ä½ 䏿˜¯ä¸æ–的把数æ®åŽ‹æ ˆï¼Œ
é€šå¸¸ä½ ä¸ç”¨å…³å¿ƒå †æ ˆå¤§å°ã€‚
å½“ä½ è°ƒç”¨ä¸€ä¸ª Lua å‡½æ•°å´æ²¡æœ‰æŒ‡å®šè¦æŽ¥æ”¶å¤šå°‘个返回值时
(å‚è§ lua_call),
Lua å¯ä»¥ä¿è¯æ ˆä¸€å®šæœ‰è¶³å¤Ÿçš„ç©ºé—´æ¥æŽ¥æ”¶æ‰€æœ‰çš„è¿”å›žå€¼ï¼Œ
但ä¸ä¿è¯æ¤å¤–留有é¢å¤–的空间。
å› æ¤ï¼Œåœ¨åšäº†ä¸€æ¬¡è¿™æ ·çš„调用åŽï¼Œå¦‚æžœä½ éœ€è¦ç»§ç»åŽ‹æ ˆï¼Œ
则需è¦ä½¿ç”¨ lua_checkstack。
API ä¸çš„函数若需è¦ä¼ å…¥æ ˆç´¢å¼•ï¼Œè¿™ä¸ªç´¢å¼•å¿…é¡»æ˜¯ 有效索引 或是 坿ޥå—索引。
有效索引 æŒ‡å¼•ç”¨æ ˆå†…çœŸå®žä½ç½®çš„索引;
å³åœ¨ 1 åˆ°æ ˆé¡¶ä¹‹é—´çš„ä½ç½®
(1 ≤ abs(index) ≤ top)。
通常,一个å¯èƒ½ä¿®æ”¹è¯¥ä½ç½®çš„值的函数需è¦ä¼ 入有效索引。
除éžå¦æœ‰è¯´æ˜Žï¼Œ 任何å¯ä»¥æŽ¥å—æœ‰æ•ˆç´¢å¼•çš„å‡½æ•°åŒæ—¶ä¹ŸæŽ¥å— 伪索引。 伪索引指代一些å¯ä»¥è¢« C code 访问得到 Lua 值,而它们åˆä¸åœ¨æ ˆå†…。 è¿™ç”¨äºŽè®¿é—®æ³¨å†Œè¡¨ä»¥åŠ C 函数的上值(å‚è§ §4.4)。
å¯¹äºŽé‚£äº›åªæ˜¯éœ€è¦æ ˆä¸çš„值(例如查询函数) 而ä¸éœ€è¦æŒ‡å®šä¸€ä¸ªæ ˆä½ç½®çš„函数, å¯ä»¥ç”¨ä¸€ä¸ªå¯æŽ¥å—的索引去调用它们。 坿ޥå—索引 ä¸ä»…å¯ä»¥æ˜¯ä»»ä½•包括伪索引在内的有效索引, 还å¯ä»¥æ˜¯ä»»ä½•è¶…è¿‡æ ˆé¡¶ä½†è½åœ¨ä¸ºæ ˆåˆ†é…出æ¥çš„空间内的æ£ç´¢å¼•。 ï¼ˆæ³¨æ„ 0 æ°¸è¿œéƒ½ä¸æ˜¯ä¸€ä¸ªå¯æŽ¥å—索引。) 除éžå¦æœ‰è¯´æ˜Žï¼ŒAPI 里的函数都接å—坿ޥå—索引。
å…è®¸å¯æŽ¥å—索引是为了é¿å…å¯¹æ ˆé¡¶ä»¥å¤–çš„æŸ¥è¯¢æ—¶åšé¢å¤–的检查。 例如,C 函数å¯ä»¥ç›´æŽ¥æŸ¥è¯¢ä¼ ç»™å®ƒçš„ç¬¬ä¸‰ä¸ªå‚æ•°ï¼Œ 而ä¸ç”¨å…ˆæ£€æŸ¥æ˜¯ä¸æ˜¯æœ‰ç¬¬ä¸‰ä¸ªå‚数, å³ä¸éœ€è¦æ£€æŸ¥ 3 æ˜¯ä¸æ˜¯ä¸€ä¸ªæœ‰æ•ˆç´¢å¼•。
对于那å¯ä»¥æŽ¥å—索引调用的函数,
æ— æ•ˆç´¢å¼•è¢«çœ‹ä½œåŒ…å«äº†ä¸€ä¸ªè™šæ‹Ÿç±»åž‹
LUA_TNONE 的值,
这个值的行为和 nil 一致。
当 C 函数被创建出æ¥ï¼Œ
我们有å¯èƒ½ä¼šæŠŠä¸€äº›å€¼å…³è”在一起,
也就是创建一个 C é—包
(å‚è§ lua_pushcclosure);
这些被关è”èµ·æ¥çš„值被å«åš 上值 ,
它们å¯ä»¥åœ¨å‡½æ•°è¢«è°ƒç”¨çš„æ—¶å€™è®¿é—®çš„到。
æ— è®ºä½•æ—¶åŽ»è°ƒç”¨ C 函数,
函数的上值都å¯ä»¥ç”¨ä¼ªç´¢å¼•定ä½ã€‚
我们å¯ä»¥ç”¨
lua_upvalueindex
è¿™ä¸ªå®æ¥ç”Ÿæˆè¿™äº›ä¼ªç´¢å¼•。
第一个关è”到函数的值放在
lua_upvalueindex(1) ä½ç½®å¤„ï¼Œä¾æ¤ç±»æŽ¨ã€‚
使用 lua_upvalueindex(n) 时,
è‹¥ n 大于当å‰å‡½æ•°çš„æ€»ä¸Šå€¼ä¸ªæ•°
(但ä¸å¯ä»¥å¤§äºŽ 256ï¼‰ä¼šäº§ç”Ÿä¸€ä¸ªå¯æŽ¥å—çš„ä½†æ— æ•ˆçš„ç´¢å¼•ã€‚
Lua æä¾›äº†ä¸€ä¸ª 注册表,
这是一个预定义出æ¥çš„表,
å¯ä»¥ç”¨æ¥ä¿å˜ä»»ä½• C ä»£ç æƒ³ä¿å˜çš„ Lua 值。
这个表å¯ä»¥ç”¨æœ‰æ•ˆä¼ªç´¢å¼•
LUA_REGISTRYINDEX æ¥å®šä½ã€‚
任何 C 库都å¯ä»¥åœ¨è¿™å¼ 表里ä¿å˜æ•°æ®ï¼Œ
为了防æ¢å†²çªï¼Œä½ 需è¦ç‰¹åˆ«å°å¿ƒçš„选择键å。
ä¸€èˆ¬çš„ç”¨æ³•æ˜¯ï¼Œä½ å¯ä»¥ç”¨ä¸€ä¸ªåŒ…å«ä½ 的库åçš„å—符串åšä¸ºé”®å,
或者å–ä½ è‡ªå·± C 对象的地å€ï¼Œä»¥è½»é‡ç”¨æˆ·æ•°æ®çš„å½¢å¼åšé”®ï¼Œ
还å¯ä»¥ç”¨ä½ 的代ç 创建出æ¥çš„ä»»æ„ Lua 对象åšé”®ã€‚
关于å˜é‡å,å—符串键åä¸ä»¥ä¸‹åˆ’çº¿åŠ å¤§å†™å—æ¯çš„åå—被 Lua ä¿ç•™ã€‚
注册表ä¸çš„æ•´æ•°é”®ç”¨äºŽå¼•用机制
(å‚è§ luaL_ref),
以åŠä¸€äº›é¢„定义的值。
å› æ¤ï¼Œæ•´æ•°é”®ä¸è¦ç”¨äºŽåˆ«çš„目的。
å½“ä½ åˆ›å»ºäº†ä¸€ä¸ªæ–°çš„ Lua çŠ¶æ€æœºï¼Œ
å…¶ä¸çš„æ³¨å†Œè¡¨å†…å°±é¢„å®šä¹‰å¥½äº†å‡ ä¸ªå€¼ã€‚
这些预定义值å¯ä»¥ç”¨æ•´æ•°ç´¢å¼•到,
这些整数以常数形å¼å®šä¹‰åœ¨ lua.h ä¸ã€‚
有下列常数:
LUA_RIDX_MAINTHREAD:
注册表ä¸è¿™ä¸ªç´¢å¼•ä¸‹æ˜¯çŠ¶æ€æœºçš„主线程。
ï¼ˆä¸»çº¿ç¨‹å’ŒçŠ¶æ€æœºåŒæ—¶è¢«åˆ›å»ºå‡ºæ¥ã€‚)
LUA_RIDX_GLOBALS:
注册表的这个索引下是全局环境。
在内部实现ä¸ï¼ŒLua 使用了 C çš„ longjmp 机制æ¥å¤„ç†é”™è¯¯ã€‚
ï¼ˆå¦‚æžœä½ ä½¿ç”¨ C++ 编译,Lua å°†æ¢æˆå¼‚常;
细节请在æºä»£ç 䏿œç´¢ LUAI_THROW。)
当 Lua 碰到任何错误
(比如内å˜åˆ†é…错误ã€ç±»åž‹é”™è¯¯ã€è¯æ³•错误ã€è¿˜æœ‰è¿è¡Œæ—¶é”™è¯¯ï¼‰
它都会 抛出一个错误出去;
也就是调用一次长跳转。
在 ä¿æŠ¤çŽ¯å¢ƒ 下,
Lua 使用 setjmp æ¥è®¾ç½®ä¸€ä¸ªæ¢å¤ç‚¹ï¼›
任何å‘生的错误都会跳转到最近的一个æ¢å¤ç‚¹ã€‚
如果错误å‘ç”Ÿåœ¨ä¿æŠ¤çŽ¯å¢ƒä¹‹å¤–ï¼Œ
Lua 会先调用 panic 函数 (å‚è§ lua_atpanic)
ç„¶åŽè°ƒç”¨ abort æ¥é€€å‡ºå®¿ä¸»ç¨‹åºã€‚
ä½ çš„ panic 函数åªè¦ä¸è¿”回
ï¼ˆä¾‹å¦‚ï¼šé•¿è·³è½¬åˆ°ä½ åœ¨ Lua å¤–ä½ è‡ªå·±è®¾ç½®çš„æ¢å¤ç‚¹ï¼‰
å°±å¯ä»¥ä¸é€€å‡ºç¨‹åºã€‚
panic 函数以错误消æ¯å¤„ç†å™¨ï¼ˆå‚è§ §2.3)的方å¼è¿è¡Œï¼› 错误消æ¯åœ¨æ ˆé¡¶ã€‚ ä¸åŒçš„æ˜¯ï¼Œå®ƒä¸ä¿è¯æ ˆç©ºé—´ã€‚ åšä»»ä½•åŽ‹æ ˆæ“作å‰ï¼Œpanic å‡½æ•°éƒ½å¿…é¡»å…ˆæ£€æŸ¥æ˜¯å¦æœ‰è¶³å¤Ÿçš„空间 (å‚è§ §4.2)。
大多数 API 函数都有å¯èƒ½æŠ›å‡ºé”™è¯¯ï¼Œ 例如在内å˜åˆ†é…错误时就会抛出。 æ¯ä¸ªå‡½æ•°çš„æ–‡æ¡£éƒ½ä¼šæ³¨æ˜Žå®ƒæ˜¯å¦å¯èƒ½æŠ›å‡ºé”™è¯¯ã€‚
在 C å‡½æ•°å†…éƒ¨ï¼Œä½ å¯ä»¥é€šè¿‡è°ƒç”¨ lua_error
æ¥æŠ›å‡ºé”™è¯¯ã€‚
Lua 内部使用 C çš„ longjmp 机制让出一个å程。
å› æ¤ï¼Œå¦‚果一个 C 函数 foo 调用了一个 API 函数,
而这个 API 函数让出了(直接或间接调用了让出函数)。
由于 longjmp 会移除 C æ ˆçš„æ ˆå¸§ï¼Œ
Lua å°±æ— æ³•è¿”å›žåˆ° foo 里了。
为了回é¿è¿™ç±»é—®é¢˜ï¼Œ
碰到 API 调用ä¸è°ƒç”¨è®©å‡ºæ—¶ï¼Œé™¤äº†é‚£äº›æŠ›å‡ºé”™è¯¯çš„ API 外,还æä¾›äº†ä¸‰ä¸ªå‡½æ•°ï¼š
lua_yieldk,
lua_callk,和 lua_pcallk 。
它们在让出å‘生时,å¯ä»¥ä»Žä¼ 入的 å»¶ç»å‡½æ•°
(å为 k çš„å‚æ•°ï¼‰ç»§ç»è¿è¡Œã€‚
我们需è¦é¢„è®¾ä¸€äº›æœ¯è¯æ¥è§£é‡Šå»¶ç»ç‚¹ã€‚
对于从 Lua ä¸è°ƒç”¨çš„ C 函数,我们称之为 原函数。
从这个原函数ä¸è°ƒç”¨çš„ä¸Šé¢æ‰€è¿°çš„三个 C API 函数我们称之为 被调函数。
被调函数å¯ä»¥ä½¿å½“å‰çº¿ç¨‹è®©å‡ºã€‚
(让出å‘生在被调函数是 lua_yieldk,
æˆ–ä¼ å…¥ lua_callk 或
lua_pcallk 的函数调用了让出时。)
å‡è®¾æ£åœ¨è¿è¡Œçš„线程在执行被调函数时让出。 当冿¬¡å»¶ç»è¿™æ¡çº¿ç¨‹ï¼Œå®ƒå¸Œæœ›ç»§ç»è¢«è°ƒå‡½æ•°çš„è¿è¡Œã€‚ 然而,被调函数ä¸å¯èƒ½è¿”回到原函数ä¸ã€‚ è¿™æ˜¯å› ä¸ºä¹‹å‰çš„让出æ“ä½œç ´å了 C æ ˆçš„æ ˆå¸§ã€‚ 作为替代å“,Lua è°ƒç”¨é‚£ä¸ªä½œä¸ºè¢«è°ƒå‡½æ•°å‚æ•°ç»™å‡ºçš„ å»¶ç»å‡½æ•° 。 æ£å¦‚å…¶å,延ç»å‡½æ•°å°†å»¶ç»åŽŸå‡½æ•°çš„ä»»åŠ¡ã€‚
下é¢çš„函数会åšä¸€ä¸ªè¯´æ˜Žï¼š
int original_function (lua_State *L) {
... /* code 1 */
status = lua_pcall(L, n, m, h); /* calls Lua */
... /* code 2 */
}
现在我们想å…许被
lua_pcall
è¿è¡Œçš„ Lua 代ç 让出。
首先,我们把函数改写æˆè¿™ä¸ªæ ·å:
int k (lua_State *L, int status, lua_KContext ctx) {
... /* code 2 */
}
int original_function (lua_State *L) {
... /* code 1 */
return k(L, lua_pcall(L, n, m, h), ctx);
}
上é¢çš„代ç ä¸ï¼Œæ–°å‡½æ•° k
就是一个 å»¶ç»å‡½æ•°
(函数类型为 lua_KFunction)。
它的工作就是原函数ä¸è°ƒç”¨ lua_pcall
之åŽåšçš„那些事情。
现在我们必须通知 Lua è¯´ï¼Œä½ å¿…é¡»åœ¨è¢«
lua_pcall
执行的 Lua 代ç å‘ç”Ÿè¿‡ä¸æ–(错误或让出)åŽï¼Œ
还得继ç»è°ƒç”¨ k 。
æ‰€ä»¥æˆ‘ä»¬è¿˜å¾—ç»§ç»æ”¹å†™è¿™æ®µä»£ç ,把
lua_pcall æ›¿æ¢æˆ
lua_pcallk:
int original_function (lua_State *L) {
... /* code 1 */
return k(L, lua_pcallk(L, n, m, h, ctx2, k), ctx1);
}
注æ„这里那个é¢å¤–的显å¼çš„对延ç»å‡½æ•°çš„调用:
Lua ä»…åœ¨éœ€è¦æ—¶ï¼Œè¿™å¯èƒ½æ˜¯ç”±é”™è¯¯å¯¼è‡´çš„也å¯èƒ½æ˜¯å‘生了让出而需è¦ç»§ç»è¿è¡Œï¼Œæ‰ä¼šè°ƒç”¨å»¶ç»å‡½æ•°ã€‚
如果没有å‘生过任何让出,调用的函数æ£å¸¸è¿”回,
那么 lua_pcallk
ï¼ˆä»¥åŠ lua_callk)也会æ£å¸¸è¿”回。
(当然,这个例åä¸ä½ 也å¯ä»¥ä¸åœ¨ä¹‹åŽè°ƒç”¨å»¶ç»å‡½æ•°ï¼Œ
而是在原函数的调用åŽç›´æŽ¥å†™ä¸Šéœ€è¦åšçš„工作。)
除了 Lua 状æ€ï¼Œå»¶ç»å‡½æ•°è¿˜æœ‰ä¸¤ä¸ªå‚数:
一个是调用最åŽçš„状æ€ç ,å¦ä¸€ä¸ªä¸€å¼€å§‹ç”±
lua_pcallk ä¼ å…¥çš„ä¸Šä¸‹æ–‡
(ctx)。
(Lua 本身ä¸ä½¿ç”¨è¿™ä¸ªå€¼ï¼›å®ƒä»…仅从原函数转å‘这个值给延ç»å‡½æ•°ã€‚)
对于 lua_pcallk 而言,
状æ€ç å’Œ lua_pcallk
本应返回值相åŒï¼ŒåŒºåˆ«ä»…在于å‘ç”Ÿè¿‡è®©å‡ºåŽæ‰æ‰§è¡Œå®Œæ—¶ï¼Œçжæ€ç 为
LUA_YIELDï¼ˆè€Œä¸æ˜¯
LUA_OK)。
对于 lua_yieldk 和
lua_callk 而言,
调用延ç»å‡½æ•°ä¼ 入的状æ€ç 一定是
LUA_YIELD。
(对这两个函数,Lua ä¸ä¼šå› 任何错误而调用延ç»å‡½æ•°ã€‚
å› ä¸ºå®ƒä»¬å¹¶ä¸å¤„ç†é”™è¯¯ã€‚)
åŒæ ·ï¼Œå½“ä½ ä½¿ç”¨ lua_callk 时,
ä½ åº”è¯¥ç”¨ LUA_OK
作为状æ€ç æ¥è°ƒç”¨å»¶ç»å‡½æ•°ã€‚
(对于 lua_yieldk,
å‡ ä¹Žæ²¡æœ‰ä»€ä¹ˆåœ°æ–¹éœ€è¦ç›´æŽ¥è°ƒç”¨å»¶ç»å‡½æ•°ï¼Œ
å› ä¸º lua_yieldk 本身并ä¸ä¼šè¿”回。)
Lua 会把延ç»å‡½æ•°çœ‹ä½œåŽŸå‡½æ•°ã€‚
å»¶ç»å‡½æ•°å°†æŽ¥æ”¶åˆ°å’ŒåŽŸå‡½æ•°ç›¸åŒçš„ Lua æ ˆï¼Œå…¶æŽ¥æ”¶åˆ°çš„ lua 状æ€ä¹Ÿå’Œ
被调函数若返回åŽåº”该有的状æ€ä¸€è‡´ã€‚
(例如,
lua_callk 调用之åŽï¼Œ
æ ˆä¸ä¹‹å‰åŽ‹å…¥çš„å‡½æ•°å’Œè°ƒç”¨å‚æ•°éƒ½è¢«è°ƒç”¨äº§ç”Ÿçš„返回值所替代。)
这时也有相åŒçš„上值。
ç‰åˆ°å®ƒè¿”回的时候,Lua 会将其看待æˆåŽŸå‡½æ•°çš„è¿”å›žåŽ»æ“作。
è¿™é‡ŒæŒ‰å—æ¯æ¬¡åºåˆ—出了所有 C API ä¸çš„函数和类型。 æ¯ä¸ªå‡½æ•°éƒ½æœ‰ä¸€ä¸ªè¿™æ ·çš„æç¤ºï¼š [-o, +p, x]
对于第一个域,o,
æŒ‡çš„æ˜¯è¯¥å‡½æ•°ä¼šä»Žæ ˆä¸Šå¼¹å‡ºå¤šå°‘ä¸ªå…ƒç´ ã€‚
第二个域,p,
æŒ‡è¯¥å‡½æ•°ä¼šå°†å¤šå°‘ä¸ªå…ƒç´ åŽ‹æ ˆã€‚
ï¼ˆæ‰€æœ‰å‡½æ•°éƒ½ä¼šåœ¨å¼¹å‡ºå‚æ•°åŽå†æŠŠç»“æžœåŽ‹æ ˆã€‚ï¼‰
x|y è¿™ç§å½¢å¼çš„åŸŸè¡¨ç¤ºè¯¥å‡½æ•°æ ¹æ®å…·ä½“情况å¯èƒ½åŽ‹å…¥ï¼ˆæˆ–å¼¹å‡ºï¼‰
x 或 y ä¸ªå…ƒç´ ï¼›
é—®å· '?' 表示
æˆ‘ä»¬æ— æ³•ä»…é€šè¿‡å‚æ•°æ¥äº†è§£è¯¥å‡½æ•°ä¼šå¼¹å‡º/压入多少元ç´
(比如,数é‡å–å†³äºŽæ ˆä¸Šæœ‰äº›ä»€ä¹ˆï¼‰ã€‚
第三个域,x,
解释了该函数是å¦ä¼šæŠ›å‡ºé”™è¯¯ï¼š
'-' 表示该函数ç»å¯¹ä¸ä¼šæŠ›å‡ºé”™è¯¯ï¼›
'e' 表示该函数å¯èƒ½æŠ›å‡ºé”™è¯¯ï¼›
'v' 表示该函数å¯èƒ½æŠ›å‡ºæœ‰æ„义的错误。
lua_absindex[-0, +0, –]
int lua_absindex (lua_State *L, int idx);
å°†ä¸€ä¸ªå¯æŽ¥å—的索引 idx 转æ¢ä¸ºç»å¯¹ç´¢å¼•
(å³ï¼Œä¸€ä¸ªä¸ä¾èµ–æ ˆé¡¶åœ¨å“ªçš„å€¼ï¼‰ã€‚
lua_Alloctypedef 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 å³å°†åˆ†é…对象类型的编ç 。
当(且仅当)Lua 创建一个对应类型的新对象时,
osize 是
LUA_TSTRING,LUA_TTABLE,LUA_TFUNCTION,
LUA_TUSERDATA,或 LUA_TTHREAD ä¸çš„一个。
è‹¥ 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) {
(void)ud; (void)osize; /* not used */
if (nsize == 0) {
free(ptr);
return NULL;
}
else
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 对应的æ“作符è¿ç®—规则 ï¼ˆå³æœ‰å¯èƒ½è§¦å‘元方法)。
op 的值必须是下列常é‡ä¸çš„一个:
LUA_OPADD: åŠ æ³• (+)LUA_OPSUB: 凿³• (-)LUA_OPMUL: 乘法 (*)LUA_OPDIV: 浮点除法 (/)LUA_OPIDIV: å‘䏋喿•´çš„除法 (//)LUA_OPMOD: å–æ¨¡ (%)LUA_OPPOW: 乘方 (^)LUA_OPUNM: å–è´Ÿ (一元 -)LUA_OPBNOT: 按ä½å–å (~)LUA_OPBAND: 按ä½ä¸Ž (&)LUA_OPBOR: æŒ‰ä½æˆ– (|)LUA_OPBXOR: 按ä½å¼‚或 (~)LUA_OPSHL: 左移 (<<)LUA_OPSHR: å³ç§» (>>)lua_atpanic[-0, +0, –]
lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);
设置一个新的 panic 函数,并返回之å‰è®¾ç½®çš„那个。 (å‚è§ §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 会ä¿è¯è¿”å›žå€¼éƒ½æ”¾å…¥æ ˆç©ºé—´ä¸ã€‚
函数返回值将按æ£åºåŽ‹æ ˆï¼ˆç¬¬ä¸€ä¸ªè¿”å›žå€¼é¦–å…ˆåŽ‹æ ˆï¼‰ï¼Œ
å› æ¤åœ¨è°ƒç”¨ç»“æŸåŽï¼Œæœ€åŽä¸€ä¸ªè¿”å›žå€¼å°†è¢«æ”¾åœ¨æ ˆé¡¶ã€‚
被调用函数内å‘生的错误将(通过 longjmp )一直上抛。
下é¢çš„例åä¸ï¼Œè¿™è¡Œ Lua 代ç ç‰ä»·äºŽåœ¨å®¿ä¸»ç¨‹åºä¸ç”¨ C 代ç åšä¸€äº›å·¥ä½œï¼š
a = f("how", t.x, 14)
这里是 C 里的代ç :
lua_getglobal(L, "f"); /* function to be called */
lua_pushliteral(L, "how"); /* 1st argument */
lua_getglobal(L, "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_setglobal(L, "a"); /* set global 'a' */
注æ„上é¢è¿™æ®µä»£ç 是 平衡 的: 到了最åŽï¼Œå †æ ˆæ¢å¤æˆåŽŸæœ‰çš„é…置。 这是一ç§è‰¯å¥½çš„ç¼–ç¨‹ä¹ æƒ¯ã€‚
lua_callk[-(nargs + 1), +nresults, e]
void lua_callk (lua_State *L,
int nargs,
int nresults,
lua_KContext ctx,
lua_KFunction k);
这个函数的行为和 lua_call
完全一致,åªä¸è¿‡å®ƒè¿˜å…许被调用的函数让出
(å‚è§ §4.7)。
lua_CFunctiontypedef 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, "incorrect argument");
lua_error(L);
}
sum += lua_tonumber(L, i);
}
lua_pushnumber(L, sum/n); /* 第一个返回值 */
lua_pushnumber(L, sum); /* 第二个返回值 */
return 2; /* 返回值的个数 */
}
lua_checkstack[-0, +0, –]
int lua_checkstack (lua_State *L, int n);
ç¡®ä¿å †æ ˆä¸Šè‡³å°‘有 n 个é¢å¤–空ä½ã€‚
如果ä¸èƒ½æŠŠå †æ ˆæ‰©å±•到相应的尺寸,函数返回å‡ã€‚
å¤±è´¥çš„åŽŸå› åŒ…æ‹¬å°†æŠŠæ ˆæ‰©å±•åˆ°æ¯”å›ºå®šæœ€å¤§å°ºå¯¸è¿˜å¤§
ï¼ˆè‡³å°‘æ˜¯å‡ åƒä¸ªå…ƒç´ )或分é…内å˜å¤±è´¥ã€‚
这个函数永远ä¸ä¼šç¼©å°å †æ ˆï¼›
å¦‚æžœå †æ ˆå·²ç»æ¯”需è¦çš„å¤§äº†ï¼Œé‚£ä¹ˆå°±ä¿æŒåŽŸæ ·ã€‚
lua_close[-0, +0, –]
void lua_close (lua_State *L);
é”€æ¯æŒ‡å®š Lua çŠ¶æ€æœºä¸çš„æ‰€æœ‰å¯¹è±¡ (如果有垃圾收集相关的元方法的è¯ï¼Œä¼šè°ƒç”¨å®ƒä»¬ï¼‰ï¼Œ å¹¶ä¸”é‡Šæ”¾çŠ¶æ€æœºä¸ä½¿ç”¨çš„æ‰€æœ‰åЍæ€å†…å˜ã€‚ 在一些平å°ä¸Šï¼Œä½ å¯ä»¥ä¸å¿…调用这个函数, å› ä¸ºå½“å®¿ä¸»ç¨‹åºç»“æŸçš„æ—¶å€™ï¼Œæ‰€æœ‰çš„资æºå°±è‡ªç„¶è¢«é‡Šæ”¾æŽ‰äº†ã€‚ å¦ä¸€æ–¹é¢ï¼Œé•¿æœŸè¿è¡Œçš„程åºï¼Œæ¯”如一个åŽå°ç¨‹åºæˆ–是一个网站æœåŠ¡å™¨ï¼Œ 会创建出多个 Lua çŠ¶æ€æœºã€‚那么就应该在ä¸éœ€è¦æ—¶èµ¶ç´§å…³é—它们。
lua_compare[-0, +0, e]
int lua_compare (lua_State *L, int index1, int index2, int op);
比较两个 Lua 值。
当索引 index1 处的值通过 op
和索引 index2 å¤„çš„å€¼åšæ¯”è¾ƒåŽæ¡ä»¶æ»¡è¶³ï¼Œå‡½æ•°è¿”回 1 。
这个函数éµå¾ª Lua 对应的æ“ä½œè§„åˆ™ï¼ˆå³æœ‰å¯èƒ½è§¦å‘元方法)。
å之,函数返回 0。
å½“ä»»ä½•ä¸€ä¸ªç´¢å¼•æ— æ•ˆæ—¶ï¼Œå‡½æ•°ä¹Ÿä¼šè¿”å›ž 0 。
op 值必须是下列常é‡ä¸çš„一个:
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);
从索引 fromidx 处å¤åˆ¶ä¸€ä¸ªå€¼åˆ°ä¸€ä¸ªæœ‰æ•ˆç´¢å¼•
toidx 处,覆盖那里的原有值。
ä¸ä¼šå½±å“其它ä½ç½®çš„值。
lua_createtable[-0, +1, e]
void lua_createtable (lua_State *L, int narr, int nrec);
åˆ›å»ºä¸€å¼ æ–°çš„ç©ºè¡¨åŽ‹æ ˆã€‚
傿•° narr å»ºè®®äº†è¿™å¼ è¡¨ä½œä¸ºåºåˆ—ä½¿ç”¨æ—¶ä¼šæœ‰å¤šå°‘ä¸ªå…ƒç´ ï¼›
傿•° nrec å»ºè®®äº†è¿™å¼ è¡¨å¯èƒ½æ‹¥æœ‰å¤šå°‘åºåˆ—ä¹‹å¤–çš„å…ƒç´ ã€‚
Lua 会使用这些建议æ¥é¢„分é…è¿™å¼ æ–°è¡¨ã€‚
å¦‚æžœä½ çŸ¥é“è¿™å¼ è¡¨ç”¨é€”çš„æ›´å¤šä¿¡æ¯ï¼Œé¢„分é…å¯ä»¥æé«˜æ€§èƒ½ã€‚
å¦åˆ™ï¼Œä½ å¯ä»¥ä½¿ç”¨å‡½æ•° lua_newtable 。
lua_dump[-0, +0, e]
int lua_dump (lua_State *L,
lua_Writer writer,
void *data,
int strip);
把函数导出æˆäºŒè¿›åˆ¶ä»£ç å— ã€‚
å‡½æ•°æŽ¥æ”¶æ ˆé¡¶çš„ Lua 函数åšå‚数,
ç„¶åŽç”Ÿæˆå®ƒçš„二进制代ç å—。
è‹¥è¢«å¯¼å‡ºçš„ä¸œè¥¿è¢«å†æ¬¡åŠ è½½ï¼Œ
åŠ è½½çš„ç»“æžœå°±ç›¸å½“äºŽåŽŸæ¥çš„函数。
当它在产生代ç å—的时候,
lua_dump
通过调用函数 writer
(å‚è§ lua_Writer )
æ¥å†™å…¥æ•°æ®ï¼ŒåŽé¢çš„ data 傿•°ä¼šè¢«ä¼ å…¥ writer 。
如果 strip 为真,
二进制代ç å—å°†ä¸åŒ…å«è¯¥å‡½æ•°çš„调试信æ¯ã€‚
最åŽä¸€æ¬¡ç”± writer 的返回值将作为这个函数的返回值返回;
0 表示没有错误。
该函数ä¸ä¼šæŠŠ Lua å‡½æ•°å¼¹å‡ºå †æ ˆã€‚
lua_error[-1, +0, v]
int lua_error (lua_State *L);
ä»¥æ ˆé¡¶çš„å€¼ä½œä¸ºé”™è¯¯å¯¹è±¡ï¼ŒæŠ›å‡ºä¸€ä¸ª Lua 错误。
这个函数将åšä¸€æ¬¡é•¿è·³è½¬ï¼Œæ‰€ä»¥ä¸€å®šä¸ä¼šè¿”回
(å‚è§ luaL_error)。
lua_gc[-0, +0, e]
int lua_gc (lua_State *L, int what, int data);
控制垃圾收集器。
è¿™ä¸ªå‡½æ•°æ ¹æ®å…¶å‚æ•° what å‘èµ·å‡ ç§ä¸åŒçš„任务:
LUA_GCSTOP:
åœæ¢åžƒåœ¾æ”¶é›†å™¨ã€‚
LUA_GCRESTART:
é‡å¯åžƒåœ¾æ”¶é›†å™¨ã€‚
LUA_GCCOLLECT:
å‘起一次完整的垃圾收集循环。
LUA_GCCOUNT:
返回 Lua ä½¿ç”¨çš„å†…å˜æ€»é‡ï¼ˆä»¥ K å—节为å•ä½ï¼‰ã€‚
LUA_GCCOUNTB:
返回当å‰å†…å˜ä½¿ç”¨é‡é™¤ä»¥ 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 。
lua_getfield[-0, +1, e]
int lua_getfield (lua_State *L, int index, const char *k);
把 t[k] çš„å€¼åŽ‹æ ˆï¼Œ
这里的 t 是索引指å‘的值。
在 Lua ä¸ï¼Œè¿™ä¸ªå‡½æ•°å¯èƒ½è§¦å‘对应 "index" 事件对应的元方法
(å‚è§ §2.4 )。
函数将返回压入值的类型。
lua_getextraspace[-0, +0, –]
void *lua_getextraspace (lua_State *L);
返回一个 Lua çŠ¶æ€æœºä¸å…³è”的内å˜å—指针。 程åºå¯ä»¥æŠŠè¿™å—内å˜ç”¨äºŽä»»ä½•用途;而 Lua ä¸ä¼šä½¿ç”¨å®ƒã€‚
æ¯ä¸€ä¸ªæ–°çº¿ç¨‹éƒ½ä¼šæºå¸¦ä¸€å—内å˜ï¼Œ åˆå§‹åŒ–为主线程的这å—内å˜çš„副本。
默认é…置下,这å—内å˜çš„大å°ä¸ºç©ºæŒ‡é’ˆçš„大å°ã€‚
ä¸è¿‡ä½ å¯ä»¥é‡æ–°ç¼–译 Lua 设定这å—内å˜ä¸åŒçš„大å°ã€‚
(å‚è§ luaconf.h ä¸çš„ LUA_EXTRASPACE。)
lua_getglobal[-0, +1, e]
int lua_getglobal (lua_State *L, const char *name);
把全局å˜é‡
lua_geti[-0, +1, e]
int lua_geti (lua_State *L, int index, lua_Integer i);
把 t[i] çš„å€¼åŽ‹æ ˆï¼Œ
这里的 t 指给定的索引指代的值。
和在 Lua é‡Œä¸€æ ·ï¼Œè¿™ä¸ªå‡½æ•°å¯èƒ½ä¼šè§¦å‘ "index" 事件的元方法
(å‚è§ §2.4)。
返回压入值的类型。
lua_getmetatable[-0, +(0|1), –]
int lua_getmetatable (lua_State *L, int index);
å¦‚æžœè¯¥ç´¢å¼•å¤„çš„å€¼æœ‰å…ƒè¡¨ï¼Œåˆ™å°†å…¶å…ƒè¡¨åŽ‹æ ˆï¼Œè¿”å›ž 1 。 å¦åˆ™ä¸ä¼šå°†ä»»ä½•ä¸œè¥¿å…¥æ ˆï¼Œè¿”å›ž 0 。
lua_gettable[-1, +1, e]
int lua_gettable (lua_State *L, int index);
把 t[k] çš„å€¼åŽ‹æ ˆï¼Œ
这里的 t 是指索引指å‘的值,
而 k åˆ™æ˜¯æ ˆé¡¶æ”¾çš„å€¼ã€‚
è¿™ä¸ªå‡½æ•°ä¼šå¼¹å‡ºå †æ ˆä¸Šçš„é”®ï¼ŒæŠŠç»“æžœæ”¾åœ¨æ ˆä¸Šç›¸åŒä½ç½®ã€‚ 和在 Lua ä¸ä¸€æ ·ï¼Œ 这个函数å¯èƒ½è§¦å‘对应 "index" 事件的元方法 (å‚è§ §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);
æŠŠæ ˆé¡¶å…ƒç´ ç§»åŠ¨åˆ°æŒ‡å®šçš„æœ‰æ•ˆç´¢å¼•å¤„ï¼Œ 便¬¡ç§»åŠ¨è¿™ä¸ªç´¢å¼•ä¹‹ä¸Šçš„å…ƒç´ ã€‚ ä¸è¦ç”¨ä¼ªç´¢å¼•æ¥è°ƒç”¨è¿™ä¸ªå‡½æ•°ï¼Œ å› ä¸ºä¼ªç´¢å¼•æ²¡æœ‰çœŸæ£æŒ‡å‘æ ˆä¸Šçš„ä½ç½®ã€‚
lua_Integertypedef ... lua_Integer;
Lua ä¸çš„æ•´æ•°ç±»åž‹ã€‚
ç¼ºçœæ—¶ï¼Œè¿™ä¸ªå°±æ˜¯ long long,
(通常是一个 64 ä½ä»¥äºŒä¸ºè¡¥ç 的整数),
也å¯ä»¥ä¿®æ”¹å®ƒä¸º long 或 int
(通常是一个 32 ä½ä»¥äºŒä¸ºè¡¥ç 的整数)。
(å‚è§ luaconf.h ä¸çš„ LUA_INT 。)
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);
当给定索引的值是一个用户数æ®ï¼ˆæ— 论是完全的还是轻é‡çš„)时, 返回 1 ,å¦åˆ™è¿”回 0 。
lua_isyieldable[-0, +0, –]
int lua_isyieldable (lua_State *L);
如果给定的å程å¯ä»¥è®©å‡ºï¼Œè¿”回 1 ,å¦åˆ™è¿”回 0 。
lua_KContexttypedef ... lua_KContext;
å»¶ç»å‡½æ•°ä¸Šä¸‹æ–‡å‚数的类型。
这一定是一个数å—类型。
当有 intptr_t 时,被定义为 intptr_t ,
å› æ¤å®ƒä¹Ÿå¯ä»¥ä¿å˜æŒ‡é’ˆã€‚
å¦åˆ™ï¼Œå®ƒè¢«å®šä¹‰ä¸º ptrdiff_t。
lua_KFunctiontypedef 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)。
它有å¯èƒ½è§¦å‘ "length" 事件对应的元方法
(å‚è§ §2.4 )。
ç»“æžœåŽ‹æ ˆã€‚
lua_load[-0, +1, –]
int lua_load (lua_State *L,
lua_Reader reader,
void *data,
const char *chunkname,
const char *mode);
åŠ è½½ä¸€æ®µ Lua 代ç å—,但ä¸è¿è¡Œå®ƒã€‚
如果没有错误,
lua_load 把一个编译好的代ç å—作为一个 Lua å‡½æ•°åŽ‹åˆ°æ ˆé¡¶ã€‚
å¦åˆ™ï¼ŒåŽ‹å…¥é”™è¯¯æ¶ˆæ¯ã€‚
lua_load 的返回值å¯ä»¥æ˜¯ï¼š
LUA_OK: 没有错误;LUA_ERRSYNTAX:
åœ¨é¢„ç¼–è¯‘æ—¶ç¢°åˆ°è¯æ³•错误;LUA_ERRMEM:
内å˜åˆ†é…错误;LUA_ERRGCMM:
在è¿è¡Œ __gc 元方法时出错了。
(这个错误和代ç å—åŠ è½½è¿‡ç¨‹æ— å…³ï¼Œå®ƒæ˜¯ç”±åžƒåœ¾æ”¶é›†å™¨å¼•å‘的。)
lua_load 函数使用一个用户æä¾›çš„ reader
函数æ¥è¯»å–代ç å—(å‚è§ lua_Reader )。
data 傿•°ä¼šè¢«ä¼ å…¥ reader 函数。
chunkname è¿™ä¸ªå‚æ•°å¯ä»¥èµ‹äºˆä»£ç å—一个åå—,
这个åå—被用于出错信æ¯å’Œè°ƒè¯•ä¿¡æ¯ï¼ˆå‚è§ §4.9)。
lua_load 会自动检测代ç å—æ˜¯æ–‡æœ¬çš„还是二进制的,
ç„¶åŽåšå¯¹åº”çš„åŠ è½½æ“作(å‚è§ç¨‹åº luac )。
å—符串 mode 的作用和函数 load 一致。
它还å¯ä»¥æ˜¯ NULL ç‰ä»·äºŽå—符串 "bt"。
lua_load çš„å†…éƒ¨ä¼šä½¿ç”¨æ ˆï¼Œ
å› æ¤ reader å‡½æ•°å¿…é¡»æ°¸è¿œåœ¨æ¯æ¬¡è¿”回时ä¿ç•™æ ˆçš„åŽŸæ ·ã€‚
如果返回的函数有上值,
第一个上值会被设置为
ä¿å˜åœ¨æ³¨å†Œè¡¨ï¼ˆå‚è§ §4.5)
LUA_RIDX_GLOBALS 索引处的全局环境。
åœ¨åŠ è½½ä¸»ä»£ç å—æ—¶ï¼Œè¿™ä¸ªä¸Šå€¼æ˜¯ _ENV å˜é‡ï¼ˆå‚è§ §2.2)。
其它上值å‡è¢«åˆå§‹åŒ–为 nil。
lua_newstate[-0, +0, –]
lua_State *lua_newstate (lua_Alloc f, void *ud);
创建一个è¿è¡Œåœ¨æ–°çš„ç‹¬ç«‹çš„çŠ¶æ€æœºä¸çš„线程。
å¦‚æžœæ— æ³•åˆ›å»ºçº¿ç¨‹æˆ–çŠ¶æ€æœºï¼ˆç”±äºŽå†…å˜æœ‰é™ï¼‰åˆ™è¿”回 NULL。
傿•° f 是一个分é…器函数;
Lua 将通过这个函数åšçŠ¶æ€æœºå†…所有的内å˜åˆ†é…æ“作。
ç¬¬äºŒä¸ªå‚æ•° ud ï¼Œè¿™ä¸ªæŒ‡é’ˆå°†åœ¨æ¯æ¬¡è°ƒç”¨åˆ†é…器时被转入。
lua_newtable[-0, +1, e]
void lua_newtable (lua_State *L);
åˆ›å»ºä¸€å¼ ç©ºè¡¨ï¼Œå¹¶å°†å…¶åŽ‹æ ˆã€‚
它ç‰ä»·äºŽ lua_createtable(L, 0, 0) 。
lua_newthread[-0, +1, e]
lua_State *lua_newthread (lua_State *L);
åˆ›å»ºä¸€æ¡æ–°çº¿ç¨‹ï¼Œå¹¶å°†å…¶åŽ‹æ ˆï¼Œ
并返回维护这个线程的 lua_State 指针。
这个函数返回的新线程共享原线程的全局环境, 但是它有独立的è¿è¡Œæ ˆã€‚
没有显å¼çš„函数å¯ä»¥ç”¨æ¥å…³é—æˆ–é”€æ¯æŽ‰ä¸€ä¸ªçº¿ç¨‹ã€‚ 线程跟其它 Lua å¯¹è±¡ä¸€æ ·æ˜¯åžƒåœ¾æ”¶é›†çš„æ¡ç›®ä¹‹ä¸€ã€‚
lua_newuserdata[-0, +1, e]
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 (什么也ä¸åŽ‹æ ˆï¼‰ã€‚
典型的éåŽ†æ–¹æ³•æ˜¯è¿™æ ·çš„ï¼š
/* 表放在索引 't' 处 */
lua_pushnil(L); /* 第一个键 */
while (lua_next(L, t) != 0) {
/* 使用 '键' (在索引 -2 处) 和 '值' (在索引 -1 处)*/
printf("%s - %s\n",
lua_typename(L, lua_type(L, -2)),
lua_typename(L, lua_type(L, -1)));
/* 移除 '值' ï¼›ä¿ç•™ 'é”®' åšä¸‹ä¸€æ¬¡è¿ä»£ */
lua_pop(L, 1);
}
在éåŽ†ä¸€å¼ è¡¨çš„æ—¶å€™ï¼Œ
ä¸è¦ç›´æŽ¥å¯¹é”®è°ƒç”¨ lua_tolstring ,
除éžä½ 知é“这个键一定是一个å—符串。
调用 lua_tolstring 有å¯èƒ½æ”¹å˜ç»™å®šç´¢å¼•ä½ç½®çš„值;
这会对下一次调用 lua_next é€ æˆå½±å“。
关于è¿ä»£è¿‡ç¨‹ä¸ä¿®æ”¹è¢«è¿ä»£çš„表的注æ„事项å‚è§ next 函数。
lua_Numbertypedef double lua_Number;
Lua 䏿µ®ç‚¹æ•°çš„类型。
Lua 䏿•°å—çš„ç±»åž‹ã€‚ç¼ºçœæ˜¯ double ï¼Œä½†æ˜¯ä½ å¯ä»¥æ”¹æˆ float 。
(å‚è§ luaconf.h ä¸çš„ LUA_REAL 。)
lua_numbertointegerint lua_numbertointeger (lua_Number n, lua_Integer *p);
将一个 Lua 浮点数转æ¢ä¸ºä¸€ä¸ª 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:
在è¿è¡Œ __gc 元方法时å‘生的错误。
ï¼ˆè¿™ä¸ªé”™è¯¯å’Œè¢«è°ƒç”¨çš„å‡½æ•°æ— å…³ã€‚ï¼‰
lua_pcallk[-(nargs + 1), +(nresults|1), –]
int lua_pcallk (lua_State *L,
int nargs,
int nresults,
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, e]
void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
把一个新的 C é—åŒ…åŽ‹æ ˆã€‚
当创建了一个 C 函数åŽï¼Œ
ä½ å¯ä»¥ç»™å®ƒå…³è”一些值,
这就是在创建一个 C é—包(å‚è§ §4.4);
æŽ¥ä¸‹æ¥æ— 论函数何时被调用,这些值都å¯ä»¥è¢«è¿™ä¸ªå‡½æ•°è®¿é—®åˆ°ã€‚
为了将一些值关è”到一个 C 函数上,
首先这些值需è¦å…ˆè¢«åŽ‹å…¥å †æ ˆï¼ˆå¦‚æžœæœ‰å¤šä¸ªå€¼ï¼Œç¬¬ä¸€ä¸ªå…ˆåŽ‹ï¼‰ã€‚
接下æ¥è°ƒç”¨ lua_pushcclosure
æ¥åˆ›å»ºå‡ºé—包并把这个 C å‡½æ•°åŽ‹åˆ°æ ˆä¸Šã€‚
傿•° n 告之函数有多少个值需è¦å…³è”到函数上。
lua_pushcclosure ä¹Ÿä¼šæŠŠè¿™äº›å€¼ä»Žæ ˆä¸Šå¼¹å‡ºã€‚
n 的最大值是 255 。
当 n 为零时,
这个函数将创建出一个 è½»é‡ C 函数,
å®ƒå°±æ˜¯ä¸€ä¸ªæŒ‡å‘ C 函数的指针。
è¿™ç§æƒ…况下,ä¸å¯èƒ½æŠ›å‡ºå†…å˜é”™è¯¯ã€‚
lua_pushcfunction[-0, +1, –]
void lua_pushcfunction (lua_State *L, lua_CFunction f);
将一个 C å‡½æ•°åŽ‹æ ˆã€‚
这个函数接收一个 C 函数指针,
并将一个类型为 function çš„ Lua å€¼åŽ‹æ ˆã€‚
å½“è¿™ä¸ªæ ˆé¡¶çš„å€¼è¢«è°ƒç”¨æ—¶ï¼Œå°†è§¦å‘对应的 C 函数。
注册到 Lua ä¸çš„任何函数都必须éµå¾ªæ£ç¡®çš„åè®®æ¥æŽ¥æ”¶å‚æ•°å’Œè¿”回值
(å‚è§ lua_CFunction )。
lua_pushcfunction 是作为一个å®å®šä¹‰å‡ºçŽ°çš„ï¼š
#define lua_pushcfunction(L,f) lua_pushcclosure(L,f,0)
lua_pushfstring[-0, +1, e]
const char *lua_pushfstring (lua_State *L, const char *fmt, ...);
æŠŠä¸€ä¸ªæ ¼å¼åŒ–过的å—ç¬¦ä¸²åŽ‹æ ˆï¼Œ
ç„¶åŽè¿”回这个å—符串的指针。
它和 C 函数 sprintf 比较åƒï¼Œ
ä¸è¿‡æœ‰ä¸€äº›é‡è¦çš„区别:
%%' (æ’入一个å—符 '%'),
'%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);
把一个轻é‡ç”¨æˆ·æ•°æ®åŽ‹æ ˆã€‚
ç”¨æˆ·æ•°æ®æ˜¯ä¿ç•™åœ¨ Lua ä¸çš„ C 值。
è½»é‡ç”¨æˆ·æ•°æ® 表示一个指针 void*。
å®ƒæ˜¯ä¸€ä¸ªåƒæ•°å—ä¸€æ ·çš„å€¼ï¼š
ä½ ä¸éœ€è¦ä¸“门创建它,它也没有独立的元表,而且也ä¸ä¼šè¢«æ”¶é›†ï¼ˆå› 为从æ¥ä¸éœ€è¦åˆ›å»ºï¼‰ã€‚
åªè¦è¡¨ç¤ºçš„ C 地å€ç›¸åŒï¼Œä¸¤ä¸ªè½»é‡ç”¨æˆ·æ•°æ®å°±ç›¸ç‰ã€‚
lua_pushliteral[-0, +1, e]
const char *lua_pushliteral (lua_State *L, const char *s);
这个å®ç‰ä»·äºŽ lua_pushstring,
区别仅在于åªèƒ½åœ¨ s 是一个å—é¢é‡æ—¶æ‰èƒ½ç”¨å®ƒã€‚
它会自动给出å—符串的长度。
lua_pushlstring[-0, +1, e]
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);
å°†ç©ºå€¼åŽ‹æ ˆã€‚
lua_pushnumber[-0, +1, –]
void lua_pushnumber (lua_State *L, lua_Number n);
把一个值为 n çš„æµ®ç‚¹æ•°åŽ‹æ ˆã€‚
lua_pushstring[-0, +1, e]
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, e]
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);
如果索引 index1 与索引 index2 处的值
本身相ç‰ï¼ˆå³ä¸è°ƒç”¨å…ƒæ–¹æ³•),返回 1 。
å¦åˆ™è¿”回 0 。
å½“ä»»ä½•ä¸€ä¸ªç´¢å¼•æ— æ•ˆæ—¶ï¼Œä¹Ÿè¿”å›ž 0 。
lua_rawget[-1, +1, –]
int lua_rawget (lua_State *L, int index);
类似于 lua_gettable ,
但是作一次直接访问(ä¸è§¦å‘元方法)。
lua_rawgeti[-0, +1, –]
int lua_rawgeti (lua_State *L, int index, lua_Integer n);
把 t[n] çš„å€¼åŽ‹æ ˆï¼Œ
这里的 t 是指给定索引处的表。
这是一次直接访问;就是说,它ä¸ä¼šè§¦å‘元方法。
è¿”å›žå…¥æ ˆå€¼çš„ç±»åž‹ã€‚
lua_rawgetp[-0, +1, –]
int lua_rawgetp (lua_State *L, int index, const void *p);
把 t[k] çš„å€¼åŽ‹æ ˆï¼Œ
这里的 t 是指给定索引处的表,
k 是指针 p 对应的轻é‡ç”¨æˆ·æ•°æ®ã€‚
这是一次直接访问;就是说,它ä¸ä¼šè§¦å‘元方法。
è¿”å›žå…¥æ ˆå€¼çš„ç±»åž‹ã€‚
lua_rawlen[-0, +0, –]
size_t lua_rawlen (lua_State *L, int index);
返回给定索引处值的固有“长度â€ï¼š
对于å—符串,它指å—符串的长度;
对于表;它指ä¸è§¦å‘元方法的情况下å–长度æ“作('#')应得到的值;
对于用户数æ®ï¼Œå®ƒæŒ‡ä¸ºè¯¥ç”¨æˆ·æ•°æ®åˆ†é…的内å˜å—的大å°ï¼›
对于其它值,它为 0 。
lua_rawset[-2, +0, e]
void lua_rawset (lua_State *L, int index);
类似于 lua_settable ,
但是是åšä¸€æ¬¡ç›´æŽ¥èµ‹å€¼ï¼ˆä¸è§¦å‘元方法)。
lua_rawseti[-1, +0, e]
void lua_rawseti (lua_State *L, int index, lua_Integer i);
ç‰ä»·äºŽ t[i] = v ,
这里的 t 是指给定索引处的表,
而 v æ˜¯æ ˆé¡¶çš„å€¼ã€‚
è¿™ä¸ªå‡½æ•°ä¼šå°†å€¼å¼¹å‡ºæ ˆã€‚ 赋值是直接的;å³ä¸ä¼šè§¦å‘元方法。
lua_rawsetp[-1, +0, e]
void lua_rawsetp (lua_State *L, int index, const void *p);
ç‰ä»·äºŽ t[k] = v ,
这里的 t 是指给定索引处的表,
k 是指针 p 对应的轻é‡ç”¨æˆ·æ•°æ®ã€‚
而 v æ˜¯æ ˆé¡¶çš„å€¼ã€‚
è¿™ä¸ªå‡½æ•°ä¼šå°†å€¼å¼¹å‡ºæ ˆã€‚ 赋值是直接的;å³ä¸ä¼šè§¦å‘元方法。
lua_Readertypedef const char * (*lua_Reader) (lua_State *L,
void *data,
size_t *size);
lua_load 用到的读å–器函数,
æ¯æ¬¡å®ƒéœ€è¦ä¸€å—新的代ç å—的时候,
lua_load 就调用读å–器,
æ¯æ¬¡éƒ½ä¼šä¼ å…¥ä¸€ä¸ªå‚æ•° data 。
读å–器需è¦è¿”å›žå«æœ‰æ–°çš„代ç å—的一å—内å˜çš„æŒ‡é’ˆï¼Œ
并把 size 设为这å—内å˜çš„大å°ã€‚
内å˜å—必须在下一次函数被调用之å‰ä¸€ç›´å˜åœ¨ã€‚
读å–器å¯ä»¥é€šè¿‡è¿”回 NULL 或设 size 为 0 æ¥æŒ‡ç¤ºä»£ç å—结æŸã€‚
读å–器å¯èƒ½è¿”回多个å—,æ¯ä¸ªå—å¯ä»¥æœ‰ä»»æ„的大于零的尺寸。
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);
在给定线程ä¸å¯åŠ¨æˆ–å»¶ç»ä¸€æ¡å程 。
è¦å¯åŠ¨ä¸€ä¸ªå程的è¯ï¼Œ
ä½ éœ€è¦æŠŠä¸»å‡½æ•°ä»¥åŠå®ƒéœ€è¦çš„傿•°åŽ‹å…¥çº¿ç¨‹æ ˆï¼›
ç„¶åŽè°ƒç”¨ lua_resume ,
把 nargs è®¾ä¸ºå‚æ•°çš„个数。
这次调用会在å程挂起时或是结æŸè¿è¡ŒåŽè¿”回。
å½“å‡½æ•°è¿”å›žæ—¶ï¼Œå †æ ˆä¸ä¼šæœ‰ä¼ ç»™ lua_yield 的所有值,
或是主函数的所有返回值。
当å程让出, lua_resume
返回 LUA_YIELD ,
è‹¥å程结æŸè¿è¡Œä¸”没有任何错误时,返回 0 。
如果有错则返回错误代ç (å‚è§ 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);
æŠŠæŒ‡å®šçŠ¶æ€æœºçš„分é…å™¨å‡½æ•°æ¢æˆå¸¦ä¸Šç”¨æˆ·æ•°æ® ud çš„ f 。
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_Statetypedef struct lua_State lua_State;
一个ä¸é€æ˜Žçš„结构, 它指å‘一æ¡çº¿ç¨‹å¹¶é—´æŽ¥ï¼ˆé€šè¿‡è¯¥çº¿ç¨‹ï¼‰å¼•用了整个 Lua 解释器的状æ€ã€‚ Lua 库是完全å¯é‡å…¥çš„: 它没有任何全局å˜é‡ã€‚ çŠ¶æ€æœºæ‰€æœ‰çš„ä¿¡æ¯éƒ½å¯ä»¥é€šè¿‡è¿™ä¸ªç»“构访问到。
è¿™ä¸ªç»“æž„çš„æŒ‡é’ˆå¿…é¡»ä½œä¸ºç¬¬ä¸€ä¸ªå‚æ•°ä¼ 递给æ¯ä¸€ä¸ªåº“函数。
lua_newstate 是一个例外,
这个函数会从头创建一个 Lua çŠ¶æ€æœºã€‚
lua_status[-0, +0, –]
int lua_status (lua_State *L);
返回线程 L 的状æ€ã€‚
æ£å¸¸çš„çº¿ç¨‹çŠ¶æ€æ˜¯ 0 (LUA_OK)。
当线程用 lua_resume 执行完毕并抛出了一个错误时,
状æ€å€¼æ˜¯é”™è¯¯ç 。
如果线程被挂起,状æ€ä¸º LUA_YIELD 。
ä½ åªèƒ½åœ¨çжæ€ä¸º LUA_OK 的线程ä¸è°ƒç”¨å‡½æ•°ã€‚
ä½ å¯ä»¥å»¶ç»ä¸€ä¸ªçжæ€ä¸º LUA_OK 的线程
(用于开始新å程)或是状æ€ä¸º LUA_YIELD 的线程
(用于延ç»å程)。
lua_stringtonumber[-0, +1, –]
size_t lua_stringtonumber (lua_State *L, const char *s);
将一个零结尾的å—符串 s 转æ¢ä¸ºä¸€ä¸ªæ•°å—,
将这个数å—åŽ‹æ ˆï¼Œå¹¶è¿”å›žå—符串的总长度(å³é•¿åº¦åŠ ä¸€ï¼‰ã€‚
转æ¢çš„结果å¯èƒ½æ˜¯æ•´æ•°ä¹Ÿå¯èƒ½æ˜¯æµ®ç‚¹æ•°ï¼Œ
è¿™å–决于 Lua 的转æ¢è¯æ³•(å‚è§ §3.1)。
这个å—符串å¯ä»¥æœ‰å‰ç½®å’ŒåŽç½®çš„ç©ºæ ¼ä»¥åŠç¬¦å·ã€‚
如果å—符串并éžä¸€ä¸ªæœ‰æ•ˆçš„æ•°å—,返回 0 å¹¶ä¸æŠŠä»»ä½•ä¸œè¥¿åŽ‹æ ˆã€‚
(注æ„,这个结果å¯ä»¥å½“æˆä¸€ä¸ªå¸ƒå°”é‡ä½¿ç”¨ï¼Œä¸ºçœŸå³è½¬æ¢æˆåŠŸã€‚ï¼‰
lua_toboolean[-0, +0, –]
int lua_toboolean (lua_State *L, int index);
把给定索引处的 Lua 值转æ¢ä¸ºä¸€ä¸ª C ä¸çš„布尔é‡ï¼ˆ 0 或是 1 )。
å’Œ Lua ä¸åšçš„æ‰€æœ‰æµ‹è¯•ä¸€æ ·ï¼Œ
lua_toboolean
会把任何ä¸åŒäºŽ false å’Œ nil 的值当作真返回;
å¦åˆ™å°±è¿”回å‡ã€‚
ï¼ˆå¦‚æžœä½ æƒ³åªæŽ¥æ”¶çœŸæ£çš„ boolean 值,
就需è¦ä½¿ç”¨ lua_isboolean æ¥æµ‹è¯•值的类型。)
lua_tocfunction[-0, +0, –]
lua_CFunction lua_tocfunction (lua_State *L, int index);
把给定索引处的 Lua 值转æ¢ä¸ºä¸€ä¸ª 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,
*isnum 会被设为æ“ä½œæ˜¯å¦æˆåŠŸã€‚
lua_tolstring[-0, +0, e]
const char *lua_tolstring (lua_State *L, int index, size_t *len);
把给定索引处的 Lua 值转æ¢ä¸ºä¸€ä¸ª C å—符串。
如果 len ä¸ä¸º NULL ,
它还把å—符串长度设到 *len ä¸ã€‚
这个 Lua 值必须是一个å—符串或是一个数å—ï¼›
å¦åˆ™è¿”回 NULL 。
如果值是一个数å—, lua_tolstring
还会 æŠŠå †æ ˆä¸çš„那个值的实际类型转æ¢ä¸ºä¸€ä¸ªå—符串。
(当éåŽ†ä¸€å¼ è¡¨çš„æ—¶å€™ï¼Œ
若把 lua_tolstring 作用在键上,
è¿™ä¸ªè½¬æ¢æœ‰å¯èƒ½å¯¼è‡´ lua_next 弄错。)
lua_tolstring è¿”å›žä¸€ä¸ªå·²å¯¹é½æŒ‡é’ˆ
æŒ‡å‘ Lua çŠ¶æ€æœºä¸çš„å—符串。
这个å—符串总能ä¿è¯ ( C è¦æ±‚的)最åŽä¸€ä¸ªå—符为零 ('\0') ,
而且它å…许在å—符串内包å«å¤šä¸ªè¿™æ ·çš„零。
å› ä¸º Lua ä¸å¯èƒ½å‘生垃圾收集,
所以ä¸ä¿è¯ lua_tolstring 返回的指针,
åœ¨å¯¹åº”çš„å€¼ä»Žå †æ ˆä¸ç§»é™¤åŽä¾ç„¶æœ‰æ•ˆã€‚
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 值转æ¢ä¸º lua_Number è¿™æ ·ä¸€ä¸ª C 类型
(å‚è§ lua_Number )。
这个 Lua å€¼å¿…é¡»æ˜¯ä¸€ä¸ªæ•°å—æˆ–是一个å¯è½¬æ¢ä¸ºæ•°å—çš„å—符串
(å‚è§ §3.4.3);
å¦åˆ™ï¼Œ lua_tonumberx 返回 0 。
如果 isnum 䏿˜¯ NULL,
*isnum 会被设为æ“ä½œæ˜¯å¦æˆåŠŸã€‚
lua_topointer[-0, +0, –]
const void *lua_topointer (lua_State *L, int index);
把给定索引处的值转æ¢ä¸ºä¸€èˆ¬çš„ C 指针 (void*) 。
这个值å¯ä»¥æ˜¯ä¸€ä¸ªç”¨æˆ·å¯¹è±¡ï¼Œè¡¨ ,线程或是一个函数;
å¦åˆ™ï¼Œ lua_topointer 返回 NULL 。
ä¸åŒçš„对象有ä¸åŒçš„æŒ‡é’ˆã€‚
ä¸å˜åœ¨æŠŠæŒ‡é’ˆå†è½¬å›žåŽŸæœ‰ç±»åž‹çš„æ–¹æ³•ã€‚
这个函数通常åªç”¨äºŽè°ƒè¯•ä¿¡æ¯ã€‚
lua_tostring[-0, +0, e]
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);
如果给定索引处的值是一个完全用户数æ®ï¼Œ
函数返回其内å˜å—的地å€ã€‚
如果值是一个轻é‡ç”¨æˆ·æ•°æ®ï¼Œ
那么就返回它表示的指针。
å¦åˆ™ï¼Œè¿”回 NULL 。
lua_type[-0, +0, –]
int lua_type (lua_State *L, int index);
返回给定有效索引处值的类型,
å½“ç´¢å¼•æ— æ•ˆï¼ˆæˆ–æ— æ³•è®¿é—®ï¼‰æ—¶åˆ™è¿”å›ž LUA_TNONE。
lua_type 返回的类型被编ç 为一些个在
lua.h ä¸å®šä¹‰çš„常é‡ï¼š
LUA_TNIL,
LUA_TNUMBER,
LUA_TBOOLEAN,
LUA_TSTRING,
LUA_TTABLE,
LUA_TFUNCTION,
LUA_TUSERDATA,
LUA_TTHREAD,
LUA_TLIGHTUSERDATA。
lua_typename[-0, +0, –]
const char *lua_typename (lua_State *L, int tp);
返回 tp 表示的类型å,
这个 tp 必须是 lua_type
å¯èƒ½è¿”回的值ä¸ä¹‹ä¸€ã€‚
lua_Unsignedtypedef ... lua_Unsigned;
lua_Integer çš„æ— ç¬¦å·ç‰ˆæœ¬ã€‚
lua_upvalueindex[-0, +0, –]
int lua_upvalueindex (int i);
返回当å‰è¿è¡Œçš„函数(å‚è§ §4.4)的第 i 个上值的伪索引。
lua_version[-0, +0, v]
const lua_Number *lua_version (lua_State *L);
返回ä¿å˜åœ¨ Lua å†…æ ¸ä¸å‚¨å˜çš„版本数å—的地å€ã€‚
å½“è°ƒç”¨æ—¶ä¼ å…¥ä¸€ä¸ªåˆæ³•çš„ lua_State ,
è¿”å›žåˆ›å»ºè¯¥çŠ¶æ€æœºæ—¶çš„版本地å€ã€‚
如果用 NULL 调用,
返回调用者的版本地å€ã€‚
lua_Writertypedef int (*lua_Writer) (lua_State *L,
const void* p,
size_t sz,
void* ud);
被 lua_dump 用到的写入器函数。
æ¯æ¬¡ lua_dump 产生了一段新的代ç å—,
它都会调用写入器。
ä¼ å…¥è¦å†™å…¥çš„缓冲区 (p) 和它的尺寸 (sz) ,
以åŠä¼ ç»™ lua_dump çš„å‚æ•° data 。
写入器会返回一个错误ç :
0 表示没有错误; 别的值å‡è¡¨ç¤ºä¸€ä¸ªé”™è¯¯ï¼Œ
并且会让 lua_dump åœæ¢å†æ¬¡è°ƒç”¨å†™å…¥å™¨ã€‚
lua_xmove[-?, +?, –]
void lua_xmove (lua_State *from, lua_State *to, int n);
交æ¢åŒä¸€ä¸ªçŠ¶æ€æœºä¸‹ä¸åŒçº¿ç¨‹ä¸çš„值。
这个函数会从 from çš„æ ˆä¸Šå¼¹å‡º n 个值,
ç„¶åŽæŠŠå®ƒä»¬åŽ‹å…¥ 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,
int nresults,
lua_KContext ctx,
lua_KFunction k);
让出å程(线程)。
当 C 函数调用了 lua_yieldk,
当å‰è¿è¡Œçš„å程会挂起,
å¯åŠ¨è¿™ä¸ªçº¿ç¨‹çš„ lua_resume 调用返回。
傿•° nresults æŒ‡æ ˆä¸Šéœ€è¿”å›žç»™
lua_resume 的返回值的个数。
当åç¨‹å†æ¬¡è¢«å»¶ç»æ—¶ï¼Œ
Lua 调用延ç»å‡½æ•° k ç»§ç»è¿è¡Œè¢«æŒ‚起(å‚è§ §4.7)的 C 函数。
å»¶ç»å‡½æ•°ä¼šä»Žå‰ä¸€ä¸ªå‡½æ•°ä¸æŽ¥æ”¶åˆ°ç›¸åŒçš„æ ˆï¼Œ
æ ˆä¸çš„ n 个返回值被移除而压入了从
lua_resume ä¼ å…¥çš„å‚æ•°ã€‚
æ¤å¤–,延ç»å‡½æ•°è¿˜ä¼šæ”¶åˆ°ä¼ ç»™ lua_yieldk
çš„å‚æ•° ctx。
通常,这个函数ä¸ä¼šè¿”回;
当å程一次次延ç»ï¼Œå°†ä»Žå»¶ç»å‡½æ•°ç»§ç»è¿è¡Œã€‚
然而,有一个例外:
当这个函数从一个é€è¡Œè¿è¡Œçš„é’©å函数(å‚è§ §4.9)
ä¸è°ƒç”¨æ—¶ï¼Œlua_yieldk ä¸å¯ä»¥æä¾›å»¶ç»å‡½æ•°ã€‚
(也就是类似 lua_yield 的形å¼ï¼‰ï¼Œ
è€Œæ¤æ—¶ï¼Œé’©å函数在调用完让出åŽå°†ç«‹åˆ»è¿”回。
Lua 会使å程让出,一旦åç¨‹å†æ¬¡è¢«å»¶ç»ï¼Œ
触å‘é’©åçš„å‡½æ•°ä¼šç»§ç»æ£å¸¸è¿è¡Œã€‚
当一个线程处于未æä¾›å»¶ç»å‡½æ•°çš„ C 调用ä¸ï¼Œè°ƒç”¨å®ƒä¼šæŠ›å‡ºä¸€ä¸ªé”™è¯¯ã€‚ 从并éžç”¨å»¶ç»æ–¹å¼ï¼ˆä¾‹å¦‚:主线程)å¯åŠ¨çš„çº¿ç¨‹ä¸è°ƒç”¨å®ƒä¹Ÿä¼šè¿™æ ·ã€‚
Lua 没有内置的调试机制。 但是它æä¾›äº†ä¸€ç»„特殊的函数接å£ä»¥åŠ é’©å。 这组接å£å¯ç”¨äºŽæž„建出ä¸åŒçš„è°ƒè¯•å™¨ã€æ€§èƒ½å‰–æžå™¨ã€ 或是其它需è¦ä»Žè§£é‡Šå™¨èŽ·å–“内部信æ¯â€çš„工具。
lua_Debugtypedef 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 linedefined; /* (S) */
int lastlinedefined; /* (S) */
unsigned char nups; /* (u) ä¸Šå€¼çš„æ•°é‡ */
unsigned char nparams; /* (u) 傿•°çš„æ•°é‡ */
char isvararg; /* (u) */
char istailcall; /* (t) */
char short_src[LUA_IDSIZE]; /* (S) */
/* ç§æœ‰éƒ¨åˆ† */
其它域
} lua_Debug;
这是一个æºå¸¦æœ‰æœ‰å…³å‡½æ•°æˆ–活动记录的å„ç§ä¿¡æ¯çš„结构。
lua_getstack åªä¼šå¡«å……ç»“æž„çš„ç§æœ‰éƒ¨åˆ†ä¾›åŽé¢ä½¿ç”¨ã€‚
调用 lua_getinfo å¯ä»¥åœ¨
lua_Debug ä¸å¡«å……那些å¯è¢«ä½¿ç”¨çš„ä¿¡æ¯åŸŸã€‚
下é¢å¯¹ 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:
如果函数以尾调用形å¼è°ƒç”¨ï¼Œè¿™ä¸ªå€¼å°±ä¸ºçœŸã€‚
åœ¨è¿™ç§æƒ…况下,当层的调用者ä¸åœ¨æ ˆä¸ã€‚
nups:
函数的上值个数。
nparams:
函数固定形å‚个数
(对于 C 函数永远是 0 )。
isvararg:
如果函数是一个å¯å˜å‚数函数则为真
(对于 C 函数永远为真)。
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);
获å–一个é—包的上值信æ¯ã€‚
(对于 Lua 函数,上值是函数需è¦ä½¿ç”¨çš„外部局部å˜é‡ï¼Œ
å› æ¤è¿™äº›å˜é‡è¢«åŒ…å«åœ¨é—包ä¸ã€‚)
lua_getupvalue 获å–第 n 个上值,
æŠŠè¿™ä¸ªä¸Šå€¼çš„å€¼åŽ‹æ ˆï¼Œ
并且返回它的åå—。
funcindex 指å‘é—åŒ…åœ¨æ ˆä¸Šçš„ä½ç½®ã€‚
( å› ä¸ºä¸Šå€¼åœ¨æ•´ä¸ªå‡½æ•°ä¸éƒ½æœ‰æ•ˆï¼Œæ‰€ä»¥å®ƒä»¬æ²¡æœ‰ç‰¹åˆ«çš„æ¬¡åºã€‚
å› æ¤ï¼Œå®ƒä»¬ä»¥å—æ¯æ¬¡åºæ¥ç¼–å·ã€‚)
å½“ç´¢å¼•å·æ¯”上值数é‡å¤§çš„æ—¶å€™ï¼Œ
返回 NULL(而且ä¸ä¼šåŽ‹å…¥ä»»ä½•ä¸œè¥¿ï¼‰ã€‚
对于 C 函数,所有上值的åå—都是空串 ""。
lua_Hooktypedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
用于调试的钩å函数类型。
æ— è®ºä½•æ—¶é’©åè¢«è°ƒç”¨ï¼Œå®ƒçš„å‚æ•° ar
ä¸çš„ event 域都被设为触å‘é’©å的事件。
Lua 把这些事件定义为以下常é‡ï¼š
LUA_HOOKCALL,LUA_HOOKRET,
LUA_HOOKTAILCALL,LUA_HOOKLINE,
LUA_HOOKCOUNT。
除æ¤ä¹‹å¤–,对于 line 事件, currentline 域也被设置。
è¦æƒ³èŽ·å¾— ar ä¸çš„其他域,
é’©å必须调用 lua_getinfo 。
对于 call 事件,event å¯ä»¥æ˜¯ LUA_HOOKCALL 这个通常值,
或是 LUA_HOOKTAILCALL 表示尾调用;
åŽä¸€ç§æƒ…况,没有对应的返回事件。
当 Lua è¿è¡Œåœ¨ä¸€ä¸ªé’©å内部时, 它将å±è”½æŽ‰å…¶å®ƒå¯¹é’©å的调用。 也就是说,如果一个钩å函数内å†è°ƒå›ž Lua æ¥æ‰§è¡Œä¸€ä¸ªå‡½æ•°æˆ–是一个代ç å— ï¼Œ 这个执行æ“作ä¸ä¼šè§¦å‘任何的钩å。
é’©å函数ä¸èƒ½æœ‰å»¶ç»ç‚¹ï¼Œ
å³ä¸èƒ½ç”¨ä¸€ä¸ªéžç©ºçš„ k 调用
lua_yieldk,
lua_pcallk,或 lua_callk。
é’©å函数å¯ä»¥åœ¨æ»¡è¶³ä¸‹åˆ—æ¡ä»¶æ—¶è®©å‡ºï¼š
åªæœ‰è¡Œè®¡æ•°äº‹ä»¶å¯ä»¥è®©å‡ºï¼Œä¸”ä¸èƒ½åœ¨è®©å‡ºæ—¶ä¼ 出任何值;
从钩å里让出必须用 lua_yield
æ¥ç»“æŸé’©åçš„è¿è¡Œï¼Œä¸” nresults 必须为零。
lua_sethook[-0, +0, –]
void lua_sethook (lua_State *L, lua_Hook f, int mask, int count);
设置一个调试用钩å函数。
傿•° f 是钩å函数。
mask 指定在哪些事件时会调用:
它由下列一组ä½å¸¸é‡æž„æˆ
LUA_MASKCALL,
LUA_MASKRET,
LUA_MASKLINE,
LUA_MASKCOUNT。
傿•° count åªåœ¨æŽ©ç ä¸åŒ…嫿œ‰ LUA_MASKCOUNT æ‰æœ‰æ„义。
对于æ¯ä¸ªäº‹ä»¶ï¼Œé’©å被调用的情况解释如下:
count æ¡æŒ‡ä»¤åŽè¢«è°ƒç”¨ã€‚
(这个事件仅仅在 Lua 执行一个 Lua 函数时å‘生。)
é’©åå¯ä»¥é€šè¿‡è®¾ç½® mask 为零å±è”½ã€‚
lua_setlocal[-(0|1), +0, –]
const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
设置给定活动记录ä¸çš„局部å˜é‡çš„值。
傿•° ar 与 n å’Œ
lua_getlocal ä¸çš„ä¸€æ ·
(å‚è§ lua_getlocal )。
lua_setlocal æŠŠæ ˆé¡¶çš„å€¼èµ‹ç»™å˜é‡ç„¶åŽè¿”回å˜é‡çš„åå—。
å®ƒä¼šå°†å€¼ä»Žæ ˆé¡¶å¼¹å‡ºã€‚
当索引大于活动局部å˜é‡çš„æ•°é‡æ—¶ï¼Œè¿”回 NULL (什么也ä¸å¼¹å‡ºï¼‰ã€‚
lua_setupvalue[-(0|1), +0, –]
const char *lua_setupvalue (lua_State *L, int funcindex, int n);
设置é—包上值的值。
å®ƒæŠŠæ ˆé¡¶çš„å€¼å¼¹å‡ºå¹¶èµ‹äºŽä¸Šå€¼å¹¶è¿”å›žä¸Šå€¼çš„åå—。
傿•° funcindex 与 n å’Œ
lua_getupvalue ä¸çš„ä¸€æ ·
(å‚è§ lua_getupvalue )。
å½“ç´¢å¼•å¤§äºŽä¸Šå€¼çš„æ•°é‡æ—¶ï¼Œè¿”回 NULL (什么也ä¸å¼¹å‡ºï¼‰ã€‚
lua_upvalueid[-0, +0, –]
void *lua_upvalueid (lua_State *L, int funcindex, int n);
返回索引 funcindex 处的é—包ä¸
ç¼–å·ä¸º n çš„ä¸Šå€¼çš„ä¸€ä¸ªå”¯ä¸€æ ‡è¯†ç¬¦ã€‚
傿•° funcindex 与 n å’Œ
lua_getupvalue ä¸çš„ä¸€æ ·
(å‚è§ lua_getupvalue )。
(但 n ä¸å¯ä»¥å¤§äºŽä¸Šå€¼çš„æ•°é‡ï¼‰ã€‚
è¿™äº›å”¯ä¸€æ ‡è¯†ç¬¦å¯ç”¨äºŽæ£€æµ‹ä¸åŒçš„é—包是å¦å…±äº«äº†ç›¸åŒçš„上值。 共享åŒä¸€ä¸ªä¸Šå€¼çš„ Lua é—包(å³å®ƒä»¬æŒ‡çš„åŒä¸€ä¸ªå¤–部局部å˜é‡ï¼‰ 会针对这个上值返回相åŒçš„æ ‡è¯†ã€‚
lua_upvaluejoin[-0, +0, –]
void lua_upvaluejoin (lua_State *L, int funcindex1, int n1,
int funcindex2, int n2);
让索引 funcindex1 处的 Lua é—包的第 n1 个上值
引用索引 funcindex2 处的 Lua é—包的第 n2 个上值。
辅助库 æä¾›äº†ä¸€äº›ä¾¿æ·å‡½æ•°ï¼Œæ–¹ä¾¿åœ¨ C ä¸ä¸º Lua 编程。 基础 API æä¾›äº† C å’Œ Lua 交互用的主è¦å‡½æ•°ï¼Œ 而辅助库则为一些常è§çš„任务æä¾›äº†é«˜é˜¶å‡½æ•°ã€‚
所有辅助库ä¸çš„函数和类型都定义在头文件 lauxlib.h ä¸ï¼Œ
它们å‡å¸¦æœ‰å‰ç¼€ luaL_。
辅助库ä¸çš„æ‰€æœ‰å‡½æ•°éƒ½åŸºäºŽåŸºç¡€ API 实现。 故而它们并没有æä¾›ä»»ä½•基础 API 实现ä¸äº†çš„功能。 虽然如æ¤ï¼Œä½¿ç”¨è¾…助库å¯ä»¥è®©ä½ çš„ä»£ç æ›´ä¸ºå¥å£®ã€‚
一些辅助库函数会在内部使用一些é¢å¤–çš„æ ˆç©ºé—´ã€‚ å½“è¾…åŠ©åº“ä½¿ç”¨çš„æ ˆç©ºé—´å°‘äºŽäº”ä¸ªæ—¶ï¼Œ 它们ä¸åŽ»æ£€æŸ¥æ ˆå¤§å°ï¼›è€Œæ˜¯ç®€å•çš„å‡è®¾æ ˆå¤Ÿç”¨ã€‚
一些辅助库ä¸çš„函数用于检查 C å‡½æ•°çš„å‚æ•°ã€‚
å› ä¸ºé”™è¯¯ä¿¡æ¯æ ¼å¼åŒ–ä¸ºæŒ‡ä»£å‚æ•°
(例如,"bad argument #1"),
ä½ å°±ä¸è¦æŠŠè¿™äº›å‡½æ•°ç”¨äºŽå‚数之外的值了。
å¦‚æžœæ£€æŸ¥æ— æ³•é€šè¿‡ï¼Œ
luaL_check* 这些函数一定会抛出错误。
è¿™é‡Œæˆ‘ä»¬æŒ‰å—æ¯è¡¨æ¬¡åºåˆ—出了辅助库ä¸çš„æ‰€æœ‰å‡½æ•°å’Œç±»åž‹ã€‚
luaL_addchar[-?, +?, e]
void luaL_addchar (luaL_Buffer *B, char c);
å‘ç¼“å˜ B (å‚è§ luaL_Buffer )
æ·»åŠ ä¸€ä¸ªå—节 c。
luaL_addlstring[-?, +?, e]
void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l);
å‘ç¼“å˜ B (å‚è§ luaL_Buffer )
æ·»åŠ ä¸€ä¸ªé•¿åº¦ä¸º l çš„å—符串 s。
这个å—符串å¯ä»¥åŒ…å«é›¶ã€‚
luaL_addsize[-?, +?, e]
void luaL_addsize (luaL_Buffer *B, size_t n);
å‘ç¼“å˜ B (å‚è§ luaL_Buffer )
æ·»åŠ ä¸€ä¸ªå·²åœ¨ä¹‹å‰å¤åˆ¶åˆ°ç¼“冲区(å‚è§ luaL_prepbuffer)
的长度为 n çš„å—符串。
luaL_addstring[-?, +?, e]
void luaL_addstring (luaL_Buffer *B, const char *s);
å‘ç¼“å˜ B (å‚è§ luaL_Buffer )
æ·»åŠ ä¸€ä¸ªé›¶ç»“å°¾çš„å—符串 s。
luaL_addvalue[-1, +?, e]
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);
抛出一个错误报告调用的 C 函数的第 arg ä¸ªå‚æ•°çš„问题。
å®ƒä½¿ç”¨ä¸‹åˆ—æ ‡å‡†ä¿¡æ¯å¹¶åŒ…å«äº†ä¸€æ®µ extramsg 作为注解:
bad argument #arg to 'funcname' (extramsg)
这个函数永远ä¸ä¼šè¿”回。
luaL_Buffertypedef struct luaL_Buffer luaL_Buffer;
å—ç¬¦ä¸²ç¼“å˜ çš„ç±»åž‹ã€‚
å—符串缓å˜å¯ä»¥è®© C 代ç åˆ†æ®µæž„é€ ä¸€ä¸ª Lua å—符串。 使用模å¼å¦‚下:
luaL_Buffer çš„å˜é‡ b。luaL_buffinit(L, &b) åˆå§‹åŒ–它。luaL_add* 这组函数å‘å…¶æ·»åŠ å—符串片æ–。
luaL_pushresult(&b) 。
最åŽè¿™æ¬¡è°ƒç”¨ä¼šåœ¨æ ˆé¡¶ç•™ä¸‹æœ€ç»ˆçš„å—符串。
å¦‚æžœä½ é¢„å…ˆçŸ¥é“结果串的长度, ä½ å¯ä»¥è¿™æ ·ä½¿ç”¨ç¼“å˜ï¼š
luaL_Buffer çš„å˜é‡ b。luaL_buffinitsize(L, &b, sz) é¢„åˆ†é… 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[-?, +?, e]
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 处的对象有元表,
且元表有域 e 。
è¿™ä¸ªå‡½æ•°ä¼šä»¥è¯¥å¯¹è±¡ä¸ºå‚æ•°è°ƒç”¨è¿™ä¸ªåŸŸã€‚
è¿™ç§æƒ…å†µä¸‹ï¼Œå‡½æ•°è¿”å›žçœŸå¹¶å°†è°ƒç”¨è¿”å›žå€¼åŽ‹æ ˆã€‚
如果那个ä½ç½®æ²¡æœ‰å…ƒè¡¨ï¼Œæˆ–没有对应的元方法,
æ¤å‡½æ•°è¿”回å‡ï¼ˆå¹¶ä¸ä¼šå°†ä»»ä½•ä¸œè¥¿åŽ‹æ ˆï¼‰ã€‚
luaL_checkany[-0, +0, v]
void luaL_checkany (lua_State *L, int arg);
检查函数在 arg ä½ç½®æ˜¯å¦æœ‰ä»»ä½•类型(包括 nilï¼‰çš„å‚æ•°ã€‚
luaL_checkinteger[-0, +0, v]
lua_Integer luaL_checkinteger (lua_State *L, int arg);
检查函数的第 arg ä¸ªå‚æ•°æ˜¯å¦æ˜¯ä¸€ä¸ª
整数(或是å¯ä»¥è¢«è½¬æ¢ä¸ºä¸€ä¸ªæ•´æ•°ï¼‰
并以 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
(比如是零结尾的å—符串数组)
䏿Ÿ¥æ‰¾è¿™ä¸ªå—符串。
返回匹é…到的å—符串在数组ä¸çš„索引å·ã€‚
å¦‚æžœå‚æ•°ä¸æ˜¯å—符串,或是å—符串在数组ä¸åŒ¹é…ä¸åˆ°ï¼Œéƒ½å°†æŠ›å‡ºé”™è¯¯ã€‚
如果 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, –]
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))
如果没有错误,函数返回å‡ï¼› 有错则返回真。
luaL_dostring[-0, +?, –]
int luaL_dostring (lua_State *L, const char *str);
åŠ è½½å¹¶è¿è¡ŒæŒ‡å®šçš„å—符串。 它是用下列å®å®šä¹‰å‡ºæ¥ï¼š
(luaL_loadstring(L, str) || lua_pcall(L, 0, LUA_MULTRET, 0))
如果没有错误,函数返回å‡ï¼› 有错则返回真。
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, e]
int luaL_execresult (lua_State *L, int stat);
è¿™ä¸ªå‡½æ•°ç”¨äºŽç”Ÿæˆæ ‡å‡†åº“ä¸å’Œè¿›ç¨‹ç›¸å…³å‡½æ•°çš„返回值。
(指 os.execute 和 io.close)。
luaL_fileresult[-0, +(1|3), e]
int luaL_fileresult (lua_State *L, int stat, const char *fname);
è¿™ä¸ªå‡½æ•°ç”¨äºŽç”Ÿæˆæ ‡å‡†åº“ä¸å’Œæ–‡ä»¶ç›¸å…³çš„函数的返回值。
(指 (io.open,
os.rename,
file:seek,ç‰ã€‚)。
luaL_getmetafield[-0, +(0|1), e]
int luaL_getmetafield (lua_State *L, int obj, const char *e);
将索引 obj å¤„å¯¹è±¡çš„å…ƒè¡¨ä¸ e åŸŸçš„å€¼åŽ‹æ ˆã€‚
如果该对象没有元表,或是该元表没有相关域,
æ¤å‡½æ•°ä»€ä¹ˆä¹Ÿä¸ä¼šåŽ‹æ ˆå¹¶è¿”å›ž LUA_TNIL。
luaL_getmetatable[-0, +1, –]
int luaL_getmetatable (lua_State *L, const char *tname);
å°†æ³¨å†Œè¡¨ä¸ tname 对应的元表
(å‚è§ luaL_newmetatableï¼‰åŽ‹æ ˆã€‚
如果没有 tname 对应的元表,则将 nil åŽ‹æ ˆå¹¶è¿”å›žå‡ã€‚
luaL_getsubtable[-0, +1, e]
int luaL_getsubtable (lua_State *L, int idx, const char *fname);
ç¡®ä¿ t[fname] æ˜¯ä¸€å¼ è¡¨ï¼Œå¹¶å°†è¿™å¼ è¡¨åŽ‹æ ˆã€‚
这里的 t 指索引 idx 处的值。
如果它原æ¥å°±æ˜¯ä¸€å¼ 表,返回真;
å¦åˆ™ä¸ºå®ƒåˆ›å»ºä¸€å¼ 新表,返回å‡ã€‚
luaL_gsub[-0, +1, e]
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, e]
int luaL_loadfile (lua_State *L, const char *filename);
ç‰ä»·äºŽ luaL_loadfilex,
å…¶ mode 傿•°ç‰äºŽ NULL。
luaL_loadfilex[-0, +1, e]
int luaL_loadfilex (lua_State *L, const char *filename,
const char *mode);
æŠŠä¸€ä¸ªæ–‡ä»¶åŠ è½½ä¸º Lua 代ç å—。
这个函数使用 lua_load åŠ è½½æ–‡ä»¶ä¸çš„æ•°æ®ã€‚
代ç å—çš„åå—被命å为 filename。
如果 filename 为 NULL,
å®ƒä»Žæ ‡å‡†è¾“å…¥åŠ è½½ã€‚
如果文件的第一行以 # 打头,则忽略这一行。
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, e]
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, e]
void luaL_newlibtable (lua_State *L, const luaL_Reg l[]);
åˆ›å»ºä¸€å¼ æ–°çš„è¡¨ï¼Œå¹¶é¢„åˆ†é…足够ä¿å˜ä¸‹æ•°ç»„ l
内容的空间(但ä¸å¡«å……)。
这是给 luaL_setfuncs
一起用的
(å‚è§ luaL_newlib)。
它以å®å½¢å¼å®žçŽ°ï¼Œ
数组 l 必须是一个数组,而ä¸èƒ½æ˜¯ä¸€ä¸ªæŒ‡é’ˆã€‚
luaL_newmetatable[-0, +1, e]
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 çŠ¶æ€æœºã€‚
å®ƒä»¥ä¸€ä¸ªåŸºäºŽæ ‡å‡† C çš„ realloc 函数实现的内å˜åˆ†é…器
调用 lua_newstate 。
å¹¶æŠŠå¯æ‰“å°ä¸€äº›å‡ºé”™ä¿¡æ¯åˆ°æ ‡å‡†é”™è¯¯è¾“出的 panic 函数(å‚è§ §4.6)
设置好,用于处ç†è‡´å‘½é”™è¯¯ã€‚
è¿”å›žæ–°çš„çŠ¶æ€æœºã€‚
如果内å˜åˆ†é…失败,则返回 NULL 。
luaL_openlibs[-0, +0, e]
void luaL_openlibs (lua_State *L);
æ‰“å¼€æŒ‡å®šçŠ¶æ€æœºä¸çš„æ‰€æœ‰ Lua æ ‡å‡†åº“ã€‚
luaL_optinteger[-0, +0, v]
lua_Integer luaL_optinteger (lua_State *L,
int arg,
lua_Integer d);
如果函数的第 arg ä¸ªå‚æ•°æ˜¯ä¸€ä¸ª
整数(或å¯ä»¥è½¬æ¢ä¸ºä¸€ä¸ªæ•´æ•°ï¼‰ï¼Œ
返回该整数。
è‹¥è¯¥å‚æ•°ä¸å˜åœ¨æˆ–是 nil,
返回 d。
除æ¤ä¹‹å¤–的情况,抛出错误。
luaL_optlstring[-0, +0, v]
const char *luaL_optlstring (lua_State *L,
int arg,
const char *d,
size_t *l);
如果函数的第 arg ä¸ªå‚æ•°æ˜¯ä¸€ä¸ª
å—符串,返回该å—符串。
è‹¥è¯¥å‚æ•°ä¸å˜åœ¨æˆ–是 nil,
返回 d。
除æ¤ä¹‹å¤–的情况,抛出错误。
è‹¥ l ä¸ä¸º NULL,
将结果的长度填入 *l 。
luaL_optnumber[-0, +0, v]
lua_Number luaL_optnumber (lua_State *L, int arg, lua_Number d);
如果函数的第 arg ä¸ªå‚æ•°æ˜¯ä¸€ä¸ª
æ•°å—,返回该数å—。
è‹¥è¯¥å‚æ•°ä¸å˜åœ¨æˆ–是 nil,
返回 d。
除æ¤ä¹‹å¤–的情况,抛出错误。
luaL_optstring[-0, +0, v]
const char *luaL_optstring (lua_State *L,
int arg,
const char *d);
如果函数的第 arg ä¸ªå‚æ•°æ˜¯ä¸€ä¸ª
å—符串,返回该å—符串。
è‹¥è¯¥å‚æ•°ä¸å˜åœ¨æˆ–是 nil,
返回 d。
除æ¤ä¹‹å¤–的情况,抛出错误。
luaL_prepbuffer[-?, +?, e]
char *luaL_prepbuffer (luaL_Buffer *B);
ç‰ä»·äºŽ luaL_prepbuffsize,
其预定义大å°ä¸º LUAL_BUFFERSIZE。
luaL_prepbuffsize[-?, +?, e]
char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz);
返回一段大å°ä¸º sz 的空间地å€ã€‚
ä½ å¯ä»¥å°†å—符串å¤åˆ¶å…¶ä¸ä»¥åŠ åˆ°ç¼“å˜ B 内
(å‚è§ luaL_Buffer)。
å°†å—符串å¤åˆ¶å…¶ä¸åŽï¼Œä½ 必须调用 luaL_addsize
ä¼ å…¥å—符串的大å°ï¼Œæ‰ä¼šçœŸæ£æŠŠå®ƒåŠ å…¥ç¼“å˜ã€‚
luaL_pushresult[-?, +1, e]
void luaL_pushresult (luaL_Buffer *B);
结æŸå¯¹ç¼“å˜ B 的使用,将最终的å—ç¬¦ä¸²ç•™åœ¨æ ˆé¡¶ã€‚
luaL_pushresultsize[-?, +1, e]
void luaL_pushresultsize (luaL_Buffer *B, size_t sz);
ç‰ä»·äºŽ luaL_addsize,luaL_pushresult。
luaL_ref[-1, +0, e]
int luaL_ref (lua_State *L, int t);
é’ˆå¯¹æ ˆé¡¶çš„å¯¹è±¡ï¼Œåˆ›å»ºå¹¶è¿”å›žä¸€ä¸ªåœ¨ç´¢å¼• t 指å‘的表ä¸çš„ 引用
(最åŽä¼šå¼¹å‡ºæ ˆé¡¶å¯¹è±¡ï¼‰ã€‚
æ¤å¼•用是一个唯一的整数键。
åªè¦ä½ ä¸å‘表 t æ‰‹å·¥æ·»åŠ æ•´æ•°é”®ï¼Œ
luaL_ref å¯ä»¥ä¿è¯å®ƒè¿”回的键的唯一性。
ä½ å¯ä»¥é€šè¿‡è°ƒç”¨ lua_rawgeti(L, t, r) æ¥æ‰¾å›žç”±
r 引用的对象。
函数 luaL_unref 用æ¥é‡Šæ”¾ä¸€ä¸ªå¼•用关è”的对象
å¦‚æžœæ ˆé¡¶çš„å¯¹è±¡æ˜¯ nil,
luaL_ref 将返回常é‡
LUA_REFNIL。
å¸¸é‡ LUA_NOREF å¯ä»¥ä¿è¯å’Œ
luaL_ref 能返回的其它引用值ä¸åŒã€‚
luaL_Regtypedef struct luaL_Reg {
const char *name;
lua_CFunction func;
} luaL_Reg;
用于 luaL_setfuncs
注册函数的数组类型。
name 指函数å,func 是函数指针。
任何 luaL_Reg 数组必须以一对
name 与 func 皆为 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, e]
void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup);
把数组 l ä¸çš„æ‰€æœ‰å‡½æ•°
(å‚è§ luaL_Reg)
æ³¨å†Œåˆ°æ ˆé¡¶çš„è¡¨ä¸ï¼ˆè¯¥è¡¨åœ¨å¯é€‰çš„上值之下,è§ä¸‹é¢çš„解说)。
è‹¥ nup ä¸ä¸ºé›¶ï¼Œ
所有的函数都共享 nup 个上值。
这些值必须在调用之å‰ï¼ŒåŽ‹åœ¨è¡¨ä¹‹ä¸Šã€‚
这些值在注册完毕åŽéƒ½ä¼šä»Žæ ˆå¼¹å‡ºã€‚
luaL_setmetatable[-0, +0, –]
void luaL_setmetatable (lua_State *L, const char *tname);
å°†æ³¨å†Œè¡¨ä¸ tname å…³è”元表
(å‚è§ luaL_newmetatable)
è®¾ä¸ºæ ˆé¡¶å¯¹è±¡çš„å…ƒè¡¨ã€‚
luaL_Streamtypedef struct luaL_Stream {
FILE *f;
lua_CFunction closef;
} luaL_Stream;
æ ‡å‡†è¾“å…¥è¾“å‡ºåº“ä¸ç”¨åˆ°çš„æ ‡å‡†æ–‡ä»¶å¥æŸ„结构。
æ–‡ä»¶å¥æŸ„实现为一个完全用户数æ®ï¼Œ
其元表被称为 LUA_FILEHANDLE
(LUA_FILEHANDLE 是一个代表真æ£å…ƒè¡¨çš„åå—çš„å®ï¼‰ã€‚
è¿™å¼ å…ƒè¡¨ç”±æ ‡å‡†è¾“å…¥è¾“å‡ºåº“ï¼ˆå‚è§ luaL_newmetatable)创建。
用户数æ®å¿…须以结构 luaL_Stream 开头;
æ¤ç»“构其åŽå¯ä»¥åŒ…å«ä»»ä½•其它数æ®ã€‚
f 域指å‘一个 C æ•°æ®æµ
(如果它为 NULL è¡¨ç¤ºä¸€ä¸ªæ²¡æœ‰åˆ›å»ºå¥½çš„å¥æŸ„)。
closef 域指å‘ä¸€ä¸ªåœ¨å…³é—æˆ–å›žæ”¶è¯¥æµæ—¶éœ€è¦è°ƒç”¨çš„ Lua 函数。
è¯¥å‡½æ•°å°†æ”¶åˆ°ä¸€ä¸ªå‚æ•°ï¼Œå³æ–‡ä»¶å¥æŸ„。
它需è¦è¿”回 true(æ“作æˆåŠŸï¼‰æˆ–
nil åŠ é”™è¯¯æ¶ˆæ¯ï¼ˆå‡ºé”™çš„æ—¶å€™ï¼‰ã€‚
一旦 Lua 调用过这个域,该域的值就会修改为 NULL
以æç¤ºè¿™ä¸ªå¥æŸ„å·²ç»è¢«å…³é—了。
luaL_testudata[-0, +0, e]
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, e]
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);
释放索引 t 处表的 ref 引用对象
(å‚è§ luaL_ref )。
æ¤æ¡ç›®ä¼šä»Žè¡¨ä¸ç§»é™¤ä»¥è®©å…¶å¼•用的对象å¯è¢«åžƒåœ¾æ”¶é›†ã€‚
而引用 ref ä¹Ÿè¢«å›žæ”¶å†æ¬¡ä½¿ç”¨ã€‚
如果 ref 为 LUA_NOREF
或 LUA_REFNIL,
luaL_unref 什么也ä¸åšã€‚
luaL_where[-0, +1, e]
void luaL_where (lua_State *L, int lvl);
将一个用于表示 lvl å±‚æ ˆçš„æŽ§åˆ¶ç‚¹ä½ç½®çš„å—ç¬¦ä¸²åŽ‹æ ˆã€‚
这个å—符串éµå¾ªä¸‹é¢çš„æ ¼å¼ï¼š
chunkname:currentline:
0 å±‚æŒ‡å½“å‰æ£åœ¨è¿è¡Œçš„函数, 1 层指调用æ£åœ¨è¿è¡Œå‡½æ•°çš„函数, 便¬¡ç±»æŽ¨ã€‚
这个函数用于构建错误消æ¯çš„å‰ç¼€ã€‚
æ ‡å‡†åº“æä¾›äº†ä¸€äº›æœ‰ç”¨çš„函数,
它们都是直接用 C API 实现的。
å…¶ä¸ä¸€äº›å‡½æ•°æä¾›äº†åŽŸæœ¬è¯è¨€å°±æœ‰çš„æœåŠ¡
(例如,type 与 getmetatable);
å¦ä¸€äº›æä¾›å’Œâ€œå¤–éƒ¨â€æ‰“交é“çš„æœåŠ¡ï¼ˆä¾‹å¦‚ I/O );
还有些本å¯ä»¥ç”¨ Lua 本身æ¥å®žçŽ°ï¼Œä½†åœ¨ C ä¸å®žçްå¯ä»¥æ»¡è¶³å…³é”®ç‚¹ä¸Šçš„æ€§èƒ½éœ€æ±‚
(例如 table.sort)。
所有的库都是直接用 C API 实现的,并以分离的 C 模å—å½¢å¼æä¾›ã€‚ ç›®å‰ï¼ŒLua æœ‰ä¸‹åˆ—æ ‡å‡†åº“ï¼š
除了基础库和包管ç†åº“, å…¶å®ƒåº“éƒ½æŠŠè‡ªå·±çš„å‡½æ•°æ”¾åœ¨ä¸€å¼ å…¨å±€è¡¨çš„åŸŸä¸ï¼Œ æˆ–æ˜¯ä»¥å¯¹è±¡æ–¹æ³•çš„å½¢å¼æä¾›ã€‚
è¦ä½¿ç”¨è¿™äº›åº“,
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 ä¸ã€‚
基础库æä¾›äº† Lua æ ¸å¿ƒå‡½æ•°ã€‚ å¦‚æžœä½ ä¸å°†è¿™ä¸ªåº“包å«åœ¨ä½ 的程åºä¸ï¼Œ ä½ å°±éœ€è¦å°å¿ƒæ£€æŸ¥ç¨‹åºæ˜¯å¦éœ€è¦è‡ªå·±æä¾›å…¶ä¸ä¸€äº›ç‰¹æ€§çš„实现。
assert (v [, message])
å¦‚æžœå…¶å‚æ•° v 的值为å‡ï¼ˆnil 或 false),
它就调用 error;
å¦åˆ™ï¼Œè¿”å›žæ‰€æœ‰çš„å‚æ•°ã€‚
在错误情况时,
message 指那个错误对象;
å¦‚æžœä¸æä¾›è¿™ä¸ªå‚æ•°ï¼Œå‚数默认为 "assertion failed!" 。
collectgarbage ([opt [, arg]])
这个函数是垃圾收集器的通用接å£ã€‚
é€šè¿‡å‚æ•° opt 它æä¾›äº†ä¸€ç»„ä¸åŒçš„功能:
collect":
åšä¸€æ¬¡å®Œæ•´çš„垃圾收集循环。
这是默认选项。
stop":
åœæ¢åžƒåœ¾æ”¶é›†å™¨çš„è¿è¡Œã€‚
在调用é‡å¯å‰ï¼Œæ”¶é›†å™¨åªä¼šå› 显å¼çš„调用è¿è¡Œã€‚
restart":
é‡å¯åžƒåœ¾æ”¶é›†å™¨çš„自动è¿è¡Œã€‚
count":
以 K å—节数为å•ä½è¿”回 Lua ä½¿ç”¨çš„æ€»å†…å˜æ•°ã€‚
è¿™ä¸ªå€¼æœ‰å°æ•°éƒ¨åˆ†ï¼Œæ‰€ä»¥åªéœ€è¦ä¹˜ä¸Š 1024 就能得到
Lua 使用的准确å—èŠ‚æ•°ï¼ˆé™¤éžæº¢å‡ºï¼‰ã€‚
step":
啿¥è¿è¡Œåžƒåœ¾æ”¶é›†å™¨ã€‚
æ¥é•¿â€œå¤§å°â€ç”± arg 控制。
ä¼ å…¥ 0 时,收集器æ¥è¿›ï¼ˆä¸å¯åˆ†å‰²çš„)一æ¥ã€‚
ä¼ å…¥éž 0 值,
收集器收集相当于 Lua 分é…这些多(K å—节)内å˜çš„工作。
如果收集器结æŸä¸€ä¸ªå¾ªçŽ¯å°†è¿”å›ž true 。
setpause":
å°† arg 设为收集器的 é—´æ‡çއ
(å‚è§ §2.5)。
返回 é—´æ‡çއ çš„å‰ä¸€ä¸ªå€¼ã€‚
setstepmul":
å°† arg 设为收集器的 æ¥è¿›å€çއ
(å‚è§ §2.5)。
返回 æ¥è¿›å€çއ çš„å‰ä¸€ä¸ªå€¼ã€‚
isrunning":
返回表示收集器是å¦åœ¨å·¥ä½œçš„布尔值
ï¼ˆå³æœªè¢«åœæ¢ï¼‰ã€‚
dofile ([filename])dofile æ‰§è¡Œæ ‡å‡†è¾“å…¥çš„å†…å®¹ï¼ˆstdin)。
返回该代ç å—的所有返回值。
对于有错误的情况,dofile 将错误å馈给调用者
(å³ï¼Œdofile 没有è¿è¡Œåœ¨ä¿æŠ¤æ¨¡å¼ä¸‹ï¼‰ã€‚
error (message [, level])message 返回。
函数 error 永远ä¸ä¼šè¿”回。
当 message 是一个å—符串时,通常 error 会把一些有关出错ä½ç½®çš„ä¿¡æ¯é™„åŠ åœ¨æ¶ˆæ¯çš„å‰å¤´ã€‚
level 傿•°æŒ‡æ˜Žäº†æ€Žæ ·èŽ·å¾—å‡ºé”™ä½ç½®ã€‚
对于 level 1 (默认值),出错ä½ç½®æŒ‡ error 函数调用的ä½ç½®ã€‚
Level 2 将出错ä½ç½®æŒ‡å‘调用 error的函数的函数;以æ¤ç±»æŽ¨ã€‚
ä¼ å…¥ level 0 å¯ä»¥é¿å…在消æ¯å‰æ·»åŠ å‡ºé”™ä½ç½®ä¿¡æ¯ã€‚
_G
getmetatable (object)
如果 object ä¸åŒ…å«å…ƒè¡¨ï¼Œè¿”回 nil 。
å¦åˆ™ï¼Œå¦‚æžœåœ¨è¯¥å¯¹è±¡çš„å…ƒè¡¨ä¸æœ‰ "__metatable" 域时返回其关è”值,
没有时返回该对象的元表。
ipairs (t)
返回三个值(è¿ä»£å‡½æ•°ã€è¡¨ t ä»¥åŠ 0 ),
如æ¤ï¼Œä»¥ä¸‹ä»£ç
for i,v in ipairs(t) do body end
å°†è¿ä»£é”®å€¼å¯¹ï¼ˆ1,t[1]) ,(2,t[2]), ... ,直到第一个空值。
load (chunk [, chunkname [, mode [, env]]])åŠ è½½ä¸€ä¸ªä»£ç å—。
如果 chunk 是一个å—符串,代ç å—æŒ‡è¿™ä¸ªå—符串。
如果 chunk 是一个函数,
load 䏿–地调用它获å–代ç å—的片æ–。
æ¯æ¬¡å¯¹ chunk 的调用都必须返回一个å—符串紧紧连接在上次调用的返回串之åŽã€‚
当返回空串ã€nilã€æˆ–是ä¸è¿”回值时,都表示代ç å—结æŸã€‚
å¦‚æžœæ²¡æœ‰è¯æ³•错误, 则以函数形å¼è¿”回编译好的代ç å—ï¼› å¦åˆ™ï¼Œè¿”回 nil åŠ ä¸Šé”™è¯¯æ¶ˆæ¯ã€‚
如果结果函数有上值,
env 被设为第一个上值。
è‹¥ä¸æä¾›æ¤å‚数,将全局环境替代它。
所有其它上值åˆå§‹åŒ–为 nil。
ï¼ˆå½“ä½ åŠ è½½ä¸»ä»£ç å—æ—¶å€™ï¼Œç»“果函数一定有且仅有一个上值 _ENV
(å‚è§ §2.2))。
ç„¶è€Œï¼Œå¦‚æžœä½ åŠ è½½ä¸€ä¸ªç”¨å‡½æ•°ï¼ˆå‚è§ string.dump,
结果函数å¯ä»¥æœ‰ä»»æ„æ•°é‡çš„上值)
创建出æ¥çš„二进制代ç å—æ—¶ï¼Œæ‰€æœ‰çš„上值都是新创建出æ¥çš„。
也就是说它们ä¸ä¼šå’Œåˆ«çš„任何函数共享。
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) æ¥åˆ¤æ–ä¸€å¼ è¡¨æ˜¯å¦æ˜¯ç©ºçš„。
索引在é历过程ä¸çš„æ¬¡åºæ— 定义, å³ä½¿æ˜¯æ•°å—ç´¢å¼•ä¹Ÿæ˜¯è¿™æ ·ã€‚ ï¼ˆå¦‚æžœæƒ³æŒ‰æ•°å—æ¬¡åºé历表,å¯ä»¥ä½¿ç”¨æ•°å—å½¢å¼çš„ for 。)
当在é历过程ä¸ä½ 给表ä¸å¹¶ä¸å˜åœ¨çš„域赋值,
next 的行为是未定义的。
ç„¶è€Œä½ å¯ä»¥åŽ»ä¿®æ”¹é‚£äº›å·²å˜åœ¨çš„域。
ç‰¹åˆ«æŒ‡å‡ºï¼Œä½ å¯ä»¥æ¸…除一些已å˜åœ¨çš„域。
pairs (t)
如果 t 有元方法 __pairs,
以 t ä¸ºå‚æ•°è°ƒç”¨å®ƒï¼Œå¹¶è¿”回其返回的å‰ä¸‰ä¸ªå€¼ã€‚
å¦åˆ™ï¼Œè¿”回三个值:next 函数,
表 tï¼Œä»¥åŠ nil。
å› æ¤ä»¥ä¸‹ä»£ç
for k,v in pairs(t) do body end
能è¿ä»£è¡¨ t ä¸çš„æ‰€æœ‰é”®å€¼å¯¹ã€‚
å‚è§å‡½æ•° next ä¸å…³äºŽè¿ä»£è¿‡ç¨‹ä¸ä¿®æ”¹è¡¨çš„风险。
pcall (f [, arg1, ···])
ä¼ å…¥å‚æ•°ï¼Œä»¥ ä¿æŠ¤æ¨¡å¼ è°ƒç”¨å‡½æ•° f 。
è¿™æ„å‘³ç€ f ä¸çš„任何错误ä¸ä¼šæŠ›å‡ºï¼›
å–而代之的是,pcall 会将错误æ•获到,并返回一个状æ€ç 。
第一个返回值是状æ€ç (一个布尔é‡ï¼‰ï¼Œ
当没有错误时,其为真。
æ¤æ—¶ï¼Œpcall åŒæ ·ä¼šåœ¨çжæ€ç åŽè¿”回所有调用的结果。
在有错误时,pcall 返回 false åŠ é”™è¯¯æ¶ˆæ¯ã€‚
print (···)stdout。
它用 tostring 函数将æ¯ä¸ªå‚数都转æ¢ä¸ºå—符串。
print ä¸ç”¨äºŽåšæ ¼å¼åŒ–输出。仅作为看一下æŸä¸ªå€¼çš„å¿«æ·æ–¹å¼ã€‚
多用于调试。
完整的对输出的控制,请使用 string.format ä»¥åŠ io.write。
rawequal (v1, v2)v1 是å¦å’Œ v2 相ç‰ã€‚
返回一个布尔é‡ã€‚
rawget (table, index)table[index] 的值。
table å¿…é¡»æ˜¯ä¸€å¼ è¡¨ï¼›
index å¯ä»¥æ˜¯ä»»ä½•值。
rawlen (v)v 的长度。
v å¯ä»¥æ˜¯è¡¨æˆ–å—符串。
它返回一个整数。
rawset (table, index, value)table[index] 设为 value。
table å¿…é¡»æ˜¯ä¸€å¼ è¡¨ï¼Œ
index å¯ä»¥æ˜¯ nil 与 NaN 之外的任何值。
value å¯ä»¥æ˜¯ä»»ä½• Lua 值。
这个函数返回 table。
select (index, ···)
如果 index 是个数å—,
é‚£ä¹ˆè¿”å›žå‚æ•°ä¸ç¬¬ index 个之åŽçš„部分;
负的数å—会从åŽå‘å‰ç´¢å¼•(-1 指最åŽä¸€ä¸ªå‚数)。
å¦åˆ™ï¼Œindex 必须是å—符串 "#",
æ¤æ—¶ select è¿”å›žå‚æ•°çš„个数。
setmetatable (table, metatable)
给指定表设置元表。
ï¼ˆä½ ä¸èƒ½åœ¨ Lua 䏿”¹å˜å…¶å®ƒç±»åž‹å€¼çš„元表,那些åªèƒ½åœ¨ C 里åšã€‚)
如果 metatable 是 nil,
将指定表的元表移除。
如果原æ¥é‚£å¼ 元表有 "__metatable" 域,抛出一个错误。
这个函数返回 table。
tonumber (e [, base])
如果调用的时候没有 base,
tonumber å°è¯•æŠŠå‚æ•°è½¬æ¢ä¸ºä¸€ä¸ªæ•°å—。
å¦‚æžœå‚æ•°å·²ç»æ˜¯ä¸€ä¸ªæ•°å—,或是一个å¯ä»¥è½¬æ¢ä¸ºæ•°å—çš„å—符串,
tonumber 就返回这个数å—ï¼›
å¦åˆ™è¿”回 nil。
å—符串的转æ¢ç»“æžœå¯èƒ½æ˜¯æ•´æ•°ä¹Ÿå¯èƒ½æ˜¯æµ®ç‚¹æ•°ï¼Œ è¿™å–决于 Lua çš„è½¬æ¢æ–‡æ³•(å‚è§ §3.1)。 (å—符串å¯ä»¥æœ‰å‰ç½®å’ŒåŽç½®çš„ç©ºæ ¼ï¼Œå¯ä»¥å¸¦ç¬¦å·ã€‚)
å½“ä¼ å…¥ base 调用它时,
e 必须是一个以该进制表示的整数å—符串。
进制å¯ä»¥æ˜¯ 2 到 36 ï¼ˆåŒ…å« 2 å’Œ 36)之间的任何整数。
大于 10 è¿›åˆ¶æ—¶ï¼Œå—æ¯ 'A' (大å°å†™å‡å¯ï¼‰è¡¨ç¤º 10 ,
'B' 表示 11ï¼Œä¾æ¬¡åˆ° 'Z' 表示 35 。
如果å—符串 e 䏿˜¯è¯¥è¿›åˆ¶ä¸‹çš„åˆæ³•æ•°å—,
函数返回 nil。
tostring (v)string.format。)
如果 v 有 "__tostring" 域的元表,
tostring 会以 v ä¸ºå‚æ•°è°ƒç”¨å®ƒã€‚
并用它的结果作为返回值。
type (v)nil" (一个å—ç¬¦ä¸²ï¼Œè€Œä¸æ˜¯ nil 值),
"number",
"string",
"boolean",
"table",
"function",
"thread",
"userdata"。
_VERSIONLua 5.3"。
xpcall (f, msgh [, arg1, ···])
这个函数和 pcall 类似。
ä¸è¿‡å®ƒå¯ä»¥é¢å¤–设置一个消æ¯å¤„ç†å™¨ msgh。
关于å程的æ“作作为基础库的一个å库,
被放在一个独立表 coroutine ä¸ã€‚
å程的介ç»å‚è§ §2.6 。
coroutine.create (f)
创建一个主体函数为 f 的新å程。
f 必须是一个 Lua 的函数。
返回这个新å程,它是一个类型为 "thread" 的对象。
coroutine.isyieldable ()如果æ£åœ¨è¿è¡Œçš„å程å¯ä»¥è®©å‡ºï¼Œåˆ™è¿”回真。
ä¸åœ¨ä¸»çº¿ç¨‹ä¸æˆ–ä¸åœ¨ä¸€ä¸ªæ— 法让出的 C å‡½æ•°ä¸æ—¶ï¼Œå½“å‰å程是å¯è®©å‡ºçš„。
coroutine.resume (co [, val1, ···])
开始或继ç»å程 co çš„è¿è¡Œã€‚
å½“ä½ ç¬¬ä¸€æ¬¡å»¶ç»ä¸€ä¸ªå程,它会从主体函数处开始è¿è¡Œã€‚
val1, ... è¿™äº›å€¼ä¼šä»¥å‚æ•°å½¢å¼ä¼ 入主体函数。
如果该å程被让出,resume ä¼šé‡æ–°å¯åŠ¨å®ƒï¼›
val1, ... è¿™äº›å‚æ•°ä¼šä½œä¸ºè®©å‡ºç‚¹çš„返回值。
如果å程è¿è¡Œèµ·æ¥æ²¡æœ‰é”™è¯¯ï¼Œ
resume 返回 true åŠ ä¸Šä¼ ç»™ yield 的所有值
(当å程让出),
或是主体函数的所有返回值(当åç¨‹ä¸æ¢ï¼‰ã€‚
如果有任何错误å‘生,
resume 返回 false åŠ é”™è¯¯æ¶ˆæ¯ã€‚
coroutine.running ()è¿”å›žå½“å‰æ£åœ¨è¿è¡Œçš„åç¨‹åŠ ä¸€ä¸ªå¸ƒå°”é‡ã€‚ 如果当å‰è¿è¡Œçš„å程是主线程,其为真。
coroutine.status (co)
以å—符串形å¼è¿”回å程 co 的状æ€ï¼š
当å程æ£åœ¨è¿è¡Œï¼ˆå®ƒå°±æ˜¯è°ƒç”¨ status 的那个) ,返回 "running"ï¼›
如果å程调用 yield 挂起或是还没有开始è¿è¡Œï¼Œè¿”回 "suspended"ï¼›
如果å程是活动的,但并ä¸åœ¨è¿è¡Œï¼ˆå³å®ƒæ£åœ¨å»¶ç»å…¶å®ƒå程),返回 "normal"ï¼›
如果å程è¿è¡Œå®Œä¸»ä½“å‡½æ•°æˆ–å› é”™è¯¯åœæ¢ï¼Œè¿”回 "dead"。
coroutine.wrap (f)
创建一个主体函数为 f 的新å程。
f 必须是一个 Lua 的函数。
返回一个函数,
æ¯æ¬¡è°ƒç”¨è¯¥å‡½æ•°éƒ½ä¼šå»¶ç»è¯¥å程。
ä¼ ç»™è¿™ä¸ªå‡½æ•°çš„å‚æ•°éƒ½ä¼šä½œä¸º resume çš„é¢å¤–傿•°ã€‚
å’Œ resume 返回相åŒçš„值,
åªæ˜¯æ²¡æœ‰ç¬¬ä¸€ä¸ªå¸ƒå°”é‡ã€‚
如果å‘生任何错误,抛出这个错误。
coroutine.yield (···)
挂起æ£åœ¨è°ƒç”¨çš„å程的执行。
ä¼ é€’ç»™ yield çš„å‚æ•°éƒ½ä¼šè½¬ä¸º resume çš„é¢å¤–返回值。
包管ç†åº“æä¾›äº†ä»Ž 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一个æè¿°æœ‰ä¸€äº›ä¸ºåŒ…管ç†å‡†å¤‡çš„编译期é…置信æ¯çš„串。 这个å—符串由一系列行构æˆï¼š
\' ,对于其它系统是 '/' 。;' 。?' 。!' 。luaopen_ å‡½æ•°åæ—¶è¢«å¿½ç•¥æŽ‰ã€‚
默认是 '-'。
package.cpath
这个路径被 require 在 C åŠ è½½å™¨ä¸åšæœç´¢æ—¶ç”¨åˆ°ã€‚
Lua 用和åˆå§‹åŒ– Lua 路径 package.path
相åŒçš„æ–¹å¼åˆå§‹åŒ– C 路径 package.cpath 。
它会使用环境å˜é‡ LUA_CPATH_5_3 或
环境å˜é‡ LUA_CPATH åˆå§‹åŒ–。
è¦ä¹ˆå°±é‡‡ç”¨ luaconf.h ä¸å®šä¹‰çš„默认路径。
package.loaded
用于 require 控制哪些模å—å·²ç»è¢«åŠ è½½çš„è¡¨ã€‚
å½“ä½ è¯·æ±‚ä¸€ä¸ª modname 模å—,且
package.loaded[modname] ä¸ä¸ºå‡æ—¶ï¼Œ
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 时,
它将查找 a 这个 C 库。
å¦‚æžœæ‰¾å¾—åˆ°ï¼Œå®ƒä¼šåœ¨é‡Œé¢æ‰¾å模å—çš„åŠ è½½å‡½æ•°ã€‚
在我们的例åä¸ï¼Œå°±æ˜¯æ‰¾ã€€luaopen_a_b_c。
利用这个机制,å¯ä»¥æŠŠè‹¥å¹² C 忍¡å—打包进å•个库。
æ¯ä¸ªå模å—都å¯ä»¥æœ‰åŽŸæœ¬çš„åŠ è½½å‡½æ•°å。
é™¤äº†ç¬¬ä¸€ä¸ªï¼ˆé¢„åŠ è½½ï¼‰æœç´¢å™¨å¤–,æ¯ä¸ªæœç´¢å™¨éƒ½ä¼šè¿”回
它找到的模å—的文件å。
这和 package.searchpath çš„è¿”å›žå€¼ä¸€æ ·ã€‚
第一个æœç´¢å™¨æ²¡æœ‰è¿”回值。
package.searchpath (name, path [, sep [, rep]])
在指定 path 䏿œç´¢æŒ‡å®šçš„ name 。
è·¯å¾„æ˜¯ä¸€ä¸ªåŒ…å«æœ‰ä¸€ç³»åˆ—以分å·åˆ†å‰²çš„ æ¨¡æ¿ æž„æˆçš„å—符串。
对于æ¯ä¸ªæ¨¡æ¿ï¼Œéƒ½ä¼šç”¨ name 替æ¢å…¶ä¸çš„æ¯ä¸ªé—®å·ï¼ˆå¦‚果有的è¯ï¼‰ã€‚
且将其ä¸çš„ sep (默认是点)替æ¢ä¸º rep
(默认是系统的目录分割符)。
ç„¶åŽå°è¯•打开这个文件å。
例如,如果路径是å—符串
"./?.lua;./?.lc;/usr/local/?/init.lua"
æœç´¢ foo.a 这个åå—å°†
便¬¡å°è¯•打开文件
./foo/a.lua , ./foo/a.lc ,以åŠ
/usr/local/foo/a/init.lua。
返回第一个å¯ä»¥ç”¨è¯»æ¨¡å¼æ‰“开(并马上关é—该文件)的文件的åå—。 如果ä¸å˜åœ¨è¿™æ ·çš„æ–‡ä»¶ï¼Œè¿”回 nil åŠ ä¸Šé”™è¯¯æ¶ˆæ¯ã€‚ (这æ¡é”™è¯¯æ¶ˆæ¯åˆ—出了所有å°è¯•打开的文件å。)
这个库æä¾›äº†å—符串处ç†çš„通用函数。 例如å—符串查找ã€åä¸²ã€æ¨¡å¼åŒ¹é…ç‰ã€‚ 当在 Lua ä¸å¯¹å—符串åšç´¢å¼•时,第一个å—符从 1 å¼€å§‹è®¡ç®—ï¼ˆè€Œä¸æ˜¯ C 里的 0 )。 索引å¯ä»¥æ˜¯è´Ÿæ•°ï¼Œå®ƒæŒ‡ä»Žå—符串末尾åå‘è§£æžã€‚ å³ï¼Œæœ€åŽä¸€ä¸ªå—符在 -1 ä½ç½®å¤„,ç‰ç‰ã€‚
å—符串库ä¸çš„æ‰€æœ‰å‡½æ•°éƒ½åœ¨è¡¨ string ä¸ã€‚
它还将其设置为å—符串元表的 __index 域。
å› æ¤ï¼Œä½ å¯ä»¥ä»¥é¢å‘对象的形å¼ä½¿ç”¨å—符串函数。
例如,string.byte(s,i) å¯ä»¥å†™æˆ s:byte(i)。
å—符串库å‡å®šé‡‡ç”¨å•å—节å—符编ç 。
string.byte (s [, i [, j]])s[i],
s[i+1], ... ,s[j]
的内部数å—ç¼–ç 。
i 的默认值是 1 ;
j 的默认值是 i。
这些索引以函数 string.sub 的规则修æ£ã€‚
æ•°å—ç¼–ç æ²¡æœ‰å¿…è¦è·¨å¹³å°ã€‚
string.char (···)æ•°å—ç¼–ç æ²¡æœ‰å¿…è¦è·¨å¹³å°ã€‚
string.dump (function [, strip])
è¿”å›žåŒ…å«æœ‰ä»¥äºŒè¿›åˆ¶æ–¹å¼è¡¨ç¤ºçš„(一个 二进制代ç å— ï¼‰æŒ‡å®šå‡½æ•°çš„å—符串。
之åŽå¯ä»¥ç”¨ load 调用这个å—符串获得
该函数的副本(但是绑定新的上值)。
如果 strip 为真值,
二进制代ç å—䏿ºå¸¦è¯¥å‡½æ•°çš„调试信æ¯
(局部å˜é‡å,行å·ï¼Œç‰ç‰ã€‚)。
带上值的函数åªä¿å˜ä¸Šå€¼çš„æ•°ç›®ã€‚ å½“ï¼ˆå†æ¬¡ï¼‰åŠ è½½æ—¶ï¼Œè¿™äº›ä¸Šå€¼è¢«æ›´æ–°ä¸º nil 的实例。 ï¼ˆä½ å¯ä»¥ä½¿ç”¨è°ƒè¯•åº“æŒ‰ä½ éœ€è¦çš„æ–¹å¼æ¥åºåˆ—化上值,并é‡è½½åˆ°å‡½æ•°ä¸ï¼‰
string.find (s, pattern [, init [, plain]])
查找第一个å—符串 s ä¸åŒ¹é…到的 pattern
(å‚è§ §6.4.1)。
如果找到一个匹é…,find 会返回 s
ä¸å…³äºŽå®ƒèµ·å§‹åŠç»ˆç‚¹ä½ç½®çš„索引;
å¦åˆ™ï¼Œè¿”回 nil。
第三个å¯é€‰æ•°å—傿•° init
指明从哪里开始æœç´¢ï¼›
默认值为 1 ï¼ŒåŒæ—¶å¯ä»¥æ˜¯è´Ÿå€¼ã€‚
第四个å¯é€‰å‚æ•° plain 为 true 时,
关闿¨¡å¼åŒ¹é…机制。
æ¤æ—¶å‡½æ•°ä»…åšç›´æŽ¥çš„ “查找å串â€çš„æ“ä½œï¼Œ
而 pattern 䏿²¡æœ‰å—ç¬¦è¢«çœ‹ä½œé”æ³•å—符。
注æ„,如果给定了 plain ,就必须写上 init 。
如果在模å¼ä¸å®šä¹‰äº†æ•获,æ•获到的若干值也会在两个索引之åŽè¿”回。
string.format (formatstring, ···)
返回ä¸å®šæ•°é‡å‚æ•°çš„æ ¼å¼åŒ–版本,
æ ¼å¼åŒ–ä¸²ä¸ºç¬¬ä¸€ä¸ªå‚æ•°ï¼ˆå¿…须是一个å—符串)。
æ ¼å¼åŒ–å—符串éµå¾ª ISO C 函数 sprintf 的规则。
ä¸åŒç‚¹åœ¨äºŽé€‰é¡¹
*, h, L, l, n,
p 䏿”¯æŒï¼Œ
å¦å¤–è¿˜å¢žåŠ äº†ä¸€ä¸ªé€‰é¡¹ q。
q 选项将一个å—ç¬¦ä¸²æ ¼å¼åŒ–为两个åŒå¼•å·æ‹¬èµ·ï¼Œå¯¹å†…部å—ç¬¦åšæ°å½“的转义处ç†çš„å—符串。
该å—符串å¯ä»¥å®‰å…¨çš„被 Lua 解释器读回æ¥ã€‚
例如,调用
string.format('%q', 'a string with "quotes" and \n new line')
会产生å—符串:
"a string with \"quotes\" and \
new line"
选项
A and a (如果有的è¯ï¼‰ï¼Œ
E, e, f,
G, and g 都期待一个对应的数å—傿•°ã€‚
选项 c, d,
i, o, u, X, and x
则期待一个整数。
选项 q 期待一个å—符串;
选项 s 期待一个没有内嵌零的å—符串。
如果选项 s å¯¹åº”çš„å‚æ•°ä¸æ˜¯å—符串,它会用和
tostring ä¸€è‡´çš„è§„åˆ™è½¬æ¢æˆå—符串。
string.gmatch (s, pattern)pattern (å‚è§ã€€§6.4.1)
对 s åšåŒ¹é…,并返回所有æ•获到的值。
如果 pattern 䏿²¡æœ‰æŒ‡å®šæ•èŽ·ï¼Œåˆ™æ¯æ¬¡æ•获整个 pattern。
下é¢è¿™ä¸ªä¾‹å会循环è¿ä»£å—符串 s 䏿‰€æœ‰çš„å•è¯ï¼Œ
å¹¶é€è¡Œæ‰“å°ï¼š
s = "hello world from Lua"
for w in string.gmatch(s, "%a+") do
print(w)
end
下一个例å从指定的å—ç¬¦ä¸²ä¸æ”¶é›†æ‰€æœ‰çš„键值对
key=value
ç½®å…¥ä¸€å¼ è¡¨ï¼š
t = {}
s = "from=world, to=Lua"
for k, v in string.gmatch(s, "(%w+)=(%w+)") do
t[k] = v
end
对这个函数æ¥è¯´ï¼Œæ¨¡æ¿å‰å¼€å§‹çš„ '^' ä¸ä¼šå½“æˆé”šç‚¹ã€‚å› ä¸ºè¿™æ ·ä¼šé˜»æ¢è¿ä»£ã€‚
string.gsub (s, pattern, repl [, n])s ä¸ï¼Œæ‰€æœ‰çš„(或是在 n ç»™å‡ºæ—¶çš„å‰ n 个)
pattern (å‚è§
§6.4.1ï¼‰éƒ½æ›¿æ¢æˆ repl ,并返回其副本。
repl å¯ä»¥æ˜¯å—符串ã€è¡¨ã€æˆ–函数。
gsub 还会在第二个返回值返回一共å‘生了多少次匹é…。
gsub 这个åå—æ¥æºäºŽ Global SUBstitution 。
如果 repl 是一个å—符串,那么把这个å—符串作为替æ¢å“。
å—符 % 是一个转义符:
repl ä¸çš„æ‰€æœ‰å½¢å¼ä¸º %d 的串表示
第 d 个æ•获到的å串,d å¯ä»¥æ˜¯ 1 到 9 。
串 %0 表示整个匹é…。
串 %% 表示å•个 %。
如果 repl æ˜¯å¼ è¡¨ï¼Œæ¯æ¬¡åŒ¹é…时都会用第一个æ•èŽ·ç‰©ä½œä¸ºé”®åŽ»æŸ¥è¿™å¼ è¡¨ã€‚
如果 repl æ˜¯ä¸ªå‡½æ•°ï¼Œåˆ™åœ¨æ¯æ¬¡åŒ¹é…å‘生时都会调用这个函数。
所有æ•获到的å䏲便¬¡ä½œä¸ºå‚æ•°ä¼ å…¥ã€‚
任何情况下,模æ¿ä¸æ²¡æœ‰è®¾å®šæ•èŽ·éƒ½çœ‹æˆæ˜¯æ•获整个模æ¿ã€‚
如果表的查询结果或函数的返回结果是一个å—符串或是个数å—, 都将其作为替æ¢ç”¨ä¸²ï¼› 而在返回 false 或 nil 时ä¸ä½œæ›¿æ¢ (å³ä¿ç•™åŒ¹é…å‰çš„原始串)。
这里有一些用例:
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 load(s)()
end)
--> 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])s 䏿‰¾åˆ°ç¬¬ä¸€ä¸ªèƒ½ç”¨ pattern
(å‚è§ §6.4.1)匹é…到的部分。
如果能找到,match 返回其ä¸çš„æ•èŽ·ç‰©ï¼›
å¦åˆ™è¿”回 nil 。
如果 pattern 䏿œªæŒ‡å®šæ•获,
返回整个 pattern æ•获到的串。
第三个å¯é€‰æ•°å—傿•° init
指明从哪里开始æœç´¢ï¼›
它默认为 1 且å¯ä»¥æ˜¯è´Ÿæ•°ã€‚
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
的长度为 j çš„å‰ç¼€ä¸²ï¼Œ
而 string.sub(s, -i) 返回长度为 i
çš„åŽç¼€ä¸²ã€‚
å¦‚æžœåœ¨å¯¹è´Ÿæ•°ç´¢å¼•è½¬ä¹‰åŽ i å°äºŽ 1 çš„è¯ï¼Œå°±ä¿®æ£å›ž 1 。
如果 j 比å—符串的长度还大,就修æ£ä¸ºå—符串长度。
如果在修æ£ä¹‹åŽï¼Œi 大于 j,
函数返回空串。
string.unpack (fmt, s [, pos])
è¿”å›žä»¥æ ¼å¼ fmt (å‚è§ §6.4.2)
打包在å—符串 s (å‚è§ string.pack)
ä¸çš„值。
选项 pos(默认为 1 ï¼‰æ ‡è®°äº†ä»Ž s
ä¸å“ªé‡Œå¼€å§‹è¯»èµ·ã€‚
读完所有的值åŽï¼Œå‡½æ•°è¿”回 s ä¸ç¬¬ä¸€ä¸ªæœªè¯»å—节的ä½ç½®ã€‚
string.upper (s)
Lua ä¸çš„åŒ¹é…æ¨¡å¼ç›´æŽ¥ç”¨å¸¸è§„çš„å—ç¬¦ä¸²æ¥æè¿°ã€‚
它用于模å¼åŒ¹é…函数
string.find,
string.gmatch,
string.gsub,
string.match。
这一节表述了这些å—ç¬¦ä¸²çš„è¯æ³•åŠå«ä¹‰ï¼ˆå³å®ƒèƒ½åŒ¹é…到什么)。
å—符类 用于表示一个å—符集åˆã€‚ 下列组åˆå¯ç”¨äºŽå—符类:
^$()%.[]*+-? ä¸çš„一员)
表示å—符 x 自身。
.: (一个点)å¯è¡¨ç¤ºä»»ä½•å—符。%a: è¡¨ç¤ºä»»ä½•å—æ¯ã€‚%c: 表示任何控制å—符。%d: 表示任何数å—。%g: è¡¨ç¤ºä»»ä½•é™¤ç©ºç™½ç¬¦å¤–çš„å¯æ‰“å°å—符。%l: 表示所有å°å†™å—æ¯ã€‚%p: è¡¨ç¤ºæ‰€æœ‰æ ‡ç‚¹ç¬¦å·ã€‚%s: 表示所有空白å—符。%u: è¡¨ç¤ºæ‰€æœ‰å¤§å†™å—æ¯ã€‚%w: è¡¨ç¤ºæ‰€æœ‰å—æ¯åŠæ•°å—。%x: 表示所有 16 进制数å—符å·ã€‚%x:
(这里的 x 是任æ„éžå—æ¯æˆ–æ•°å—çš„å—符)
表示å—符 x。
è¿™æ˜¯å¯¹é”æ³•å—ç¬¦è½¬ä¹‰çš„æ ‡å‡†æ–¹æ³•ã€‚
所有éžå—æ¯æˆ–æ•°å—çš„å—符
ï¼ˆåŒ…æ‹¬æ‰€æœ‰æ ‡ç‚¹ï¼Œä¹ŸåŒ…æ‹¬éžé”法å—符)
都å¯ä»¥ç”¨å‰ç½®ä¸€ä¸ª '%' 放在模å¼ä¸²ä¸è¡¨ç¤ºè‡ªèº«ã€‚
[set]:
表示 setã€€ä¸æ‰€æœ‰å—符的è”åˆã€‚
å¯ä»¥ä»¥ '-' 连接,å‡åºä¹¦å†™èŒƒå›´ä¸¤ç«¯çš„å—符æ¥è¡¨ç¤ºä¸€ä¸ªèŒƒå›´çš„å—符集。
ä¸Šé¢æåˆ°çš„ %x å½¢å¼ä¹Ÿå¯ä»¥åœ¨ set ä¸ä½¿ç”¨
表示其ä¸çš„ä¸€ä¸ªå…ƒç´ ã€‚
其它出现在 set ä¸çš„å—符则代表它们自己。
例如,[%w_] (或 [_%w])
è¡¨ç¤ºæ‰€æœ‰çš„å—æ¯æ•°å—åŠ ä¸‹åˆ’çº¿ï¼‰ï¼Œ
[0-7] 表示 8 进制数å—,
[0-7%l%-] 表示 8 进制数å—åŠ å°å†™å—æ¯ä¸Ž '-' å—符。
交å‰ä½¿ç”¨ç±»å’ŒèŒƒå›´çš„行为未定义。
å› æ¤ï¼Œåƒ [%a-z] 或 [a-%%]
è¿™æ ·çš„æ¨¡å¼ä¸²æ²¡æœ‰æ„义。
[^set]:
表示 set 的补集,
å…¶ä¸ set 如上é¢çš„解释。
所有å•ä¸ªå—æ¯è¡¨ç¤ºçš„类别(%a,%c,ç‰ï¼‰ï¼Œ
è‹¥å°†å…¶å—æ¯æ”¹ä¸ºå¤§å†™ï¼Œå‡è¡¨ç¤ºå¯¹åº”的补集。
例如,%S 表示所有éžç©ºæ ¼çš„å—符。
å¦‚ä½•å®šä¹‰å—æ¯ã€ç©ºæ ¼ã€æˆ–是其他å—符组å–决于当å‰çš„区域设置。
特别注æ„:[a-z] 未必ç‰ä»·äºŽ %l 。
æ¨¡å¼æ¡ç›® å¯ä»¥æ˜¯
*',
将匹é…零或多个该类的å—符。
这个æ¡ç›®æ€»æ˜¯åŒ¹é…å°½å¯èƒ½é•¿çš„串;
+',
将匹é…一或更多个该类的å—符。
这个æ¡ç›®æ€»æ˜¯åŒ¹é…å°½å¯èƒ½é•¿çš„串;
-',
将匹é…零或更多个该类的å—符。
å’Œ '*' ä¸åŒï¼Œ
这个æ¡ç›®æ€»æ˜¯åŒ¹é…å°½å¯èƒ½çŸçš„串;
?',
将匹é…零或一个该类的å—符。
åªè¦æœ‰å¯èƒ½ï¼Œå®ƒä¼šåŒ¹é…一个;
%n,
这里的 n å¯ä»¥ä»Ž 1 到 9ï¼›
这个æ¡ç›®åŒ¹é…一个ç‰äºŽ n å·æ•获物(åŽé¢æœ‰æè¿°ï¼‰çš„å串。
%bxy,
这里的 x å’Œ y 是两个明确的å—符;
这个æ¡ç›®åŒ¹é…以 x 开始 y 结æŸï¼Œ
ä¸”å…¶ä¸ x å’Œ y ä¿æŒ 平衡 çš„å—符串。
æ„æ€æ˜¯ï¼Œå¦‚果从左到å³è¯»è¿™ä¸ªå—ç¬¦ä¸²ï¼Œå¯¹æ¯æ¬¡è¯»åˆ°ä¸€ä¸ª
x 就 +1 ,读到一个 y 就 -1,
最终结æŸå¤„的那个 y 是第一个记数到 0 çš„ y。
举个例å,æ¡ç›® %b() å¯ä»¥åŒ¹é…到括å·å¹³è¡¡çš„表达å¼ã€‚
%f[set],
指 边境模å¼ï¼›
这个æ¡ç›®ä¼šåŒ¹é…到一个ä½äºŽ set 内æŸä¸ªå—符之å‰çš„一个空串,
且这个ä½ç½®çš„å‰ä¸€ä¸ªå—符ä¸å±žäºŽ set 。
é›†åˆ set çš„å«ä¹‰å¦‚å‰é¢æ‰€è¿°ã€‚
匹é…出的那个空串之开始和结æŸç‚¹çš„计算就看æˆè¯¥å¤„有个å—符
'\0' ä¸€æ ·ã€‚
æ¨¡å¼ æŒ‡ä¸€ä¸ªæ¨¡å¼æ¡ç›®çš„åºåˆ—。
åœ¨æ¨¡å¼æœ€å‰é¢åŠ ä¸Šç¬¦å· '^' 将锚定从å—符串的开始处åšåŒ¹é…。
åœ¨æ¨¡å¼æœ€åŽé¢åŠ ä¸Šç¬¦å· '$' 将使匹é…过程锚定到å—符串的结尾。
如果 '^' å’Œ '$' 出现在其它ä½ç½®ï¼Œå®ƒä»¬å‡æ²¡æœ‰ç‰¹æ®Šå«ä¹‰ï¼Œåªè¡¨ç¤ºè‡ªèº«ã€‚
模å¼å¯ä»¥åœ¨å†…éƒ¨ç”¨å°æ‹¬å·æ‹¬èµ·ä¸€ä¸ªå模å¼ï¼›
è¿™äº›åæ¨¡å¼è¢«ç§°ä¸º æ•获物。
å½“åŒ¹é…æˆåŠŸæ—¶ï¼Œç”± æ•获物 匹é…到的å—符串ä¸çš„å串被ä¿å˜èµ·æ¥ç”¨äºŽæœªæ¥çš„用途。
æ•获物以它们左括å·çš„æ¬¡åºæ¥ç¼–å·ã€‚
ä¾‹å¦‚ï¼Œå¯¹äºŽæ¨¡å¼ "(a*(.)%w(%s*))" ,
å—符串ä¸åŒ¹é…到 "a*(.)%w(%s*)" 的部分ä¿å˜åœ¨ç¬¬ä¸€ä¸ªæ•获物ä¸
ï¼ˆå› æ¤æ˜¯ç¼–å· 1 );
ç”± "." 匹é…到的å—符是 2 å·æ•获物,
匹é…到 "%s*" 的那部分是 3 å·ã€‚
作为一个特例,空的æ•获 () å°†æ•获到当å‰å—符串的ä½ç½®ï¼ˆå®ƒæ˜¯ä¸€ä¸ªæ•°å—)。
ä¾‹å¦‚ï¼Œå¦‚æžœå°†æ¨¡å¼ "()aa()" 作用到å—符串
"flaaap" 上,将产生两个æ•获物:
3 和 5 。
用于 string.pack,
string.packsize,
string.unpack
çš„ç¬¬ä¸€ä¸ªå‚æ•°ã€‚
它是一个æè¿°äº†éœ€è¦åˆ›å»ºæˆ–读å–的结构之布局。
æ ¼å¼ä¸²æ˜¯ç”±è½¬æ¢é€‰é¡¹æž„æˆçš„åºåˆ—。 这些转æ¢é€‰é¡¹åˆ—在åŽé¢ï¼š
<: 设为å°ç«¯ç¼–ç >: 设为大端编ç =: 大å°ç«¯éµå¾ªæœ¬åœ°è®¾ç½®![n]: å°†æœ€å¤§å¯¹é½æ•°è®¾ä¸º n
(默认éµå¾ªæœ¬åœ°å¯¹é½è®¾ç½®ï¼‰b: 一个有符å·å—节 (char)B: ä¸€ä¸ªæ— ç¬¦å·å—节 (char)h: ä¸€ä¸ªæœ‰ç¬¦å· short (本地大å°ï¼‰H: ä¸€ä¸ªæ— ç¬¦å· short (本地大å°ï¼‰l: ä¸€ä¸ªæœ‰ç¬¦å· long (本地大å°ï¼‰L: ä¸€ä¸ªæ— ç¬¦å· long (本地大å°ï¼‰j: 一个 lua_IntegerJ: 一个 lua_UnsignedT: 一个 size_t (本地大å°ï¼‰i[n]: 一个 n å—节长(默认为本地大å°ï¼‰çš„æœ‰ç¬¦å· intI[n]: 一个 n å—节长(默认为本地大å°ï¼‰çš„æ— ç¬¦å· intf: 一个 float (本地大å°ï¼‰d: 一个 double (本地大å°ï¼‰n: 一个 lua_Numbercn: nå—节固定长度的å—符串z: 零结尾的å—符串s[n]: é•¿åº¦åŠ å†…å®¹çš„å—符串,其长度编ç 为一个 n å—节(默认是个 size_t) é•¿çš„æ— ç¬¦å·æ•´æ•°ã€‚x: 一个å—节的填充Xop: 按选项 op 的方å¼å¯¹é½ï¼ˆå¿½ç•¥å®ƒçš„其它方é¢ï¼‰çš„一个空æ¡ç›® ': ï¼ˆç©ºæ ¼ï¼‰å¿½ç•¥
( "[n]" 表示一个å¯é€‰çš„æ•´æ•°ã€‚)
除填充ã€ç©ºæ ¼ã€é…置项(选项 "xX <=>!")外,
æ¯ä¸ªé€‰é¡¹éƒ½å…³è”ä¸€ä¸ªå‚æ•°ï¼ˆå¯¹äºŽ string.pack)
或结果(对于 string.unpack)。
对于选项 "!n", "sn", "in", "In",
n å¯ä»¥æ˜¯ 1 到 16 间的整数。
æ‰€æœ‰çš„æ•´æ•°é€‰é¡¹éƒ½å°†åšæº¢å‡ºæ£€æŸ¥ï¼›
string.pack 检查æä¾›çš„值是å¦èƒ½ç”¨æŒ‡å®šçš„å—长表示;
string.unpack 检查读出的值能å¦ç½®å…¥ Lua æ•´æ•°ä¸ã€‚
ä»»ä½•æ ¼å¼ä¸²éƒ½å‡è®¾æœ‰ä¸€ä¸ª "!1=" å‰ç¼€ï¼Œ
峿œ€å¤§å¯¹é½ä¸º 1 ï¼ˆæ— å¯¹é½ï¼‰ä¸”采用本地大å°ç«¯è®¾ç½®ã€‚
对é½è¡Œä¸ºæŒ‰å¦‚下规则工作:
对æ¯ä¸ªé€‰é¡¹ï¼Œæ ¼å¼åŒ–时都会填充一些å—节直到数æ®ä»Žä¸€ä¸ªç‰¹å®šå移处开始,
这个ä½ç½®æ˜¯è¯¥é€‰é¡¹çš„大å°å’Œæœ€å¤§å¯¹é½æ•°ä¸è¾ƒå°çš„é‚£ä¸ªæ•°çš„å€æ•°ï¼›
这个较å°å€¼å¿…须是 2 个整数次方。
选项 "c" åŠ "z" ä¸åšå¯¹é½å¤„ç†ï¼›
选项 "s" 对对é½éµå¾ªå…¶å¼€å¤´çš„æ•´æ•°ã€‚
string.pack 用零去填充
(string.unpack 则忽略它)。
这个库æä¾›äº†å¯¹ UTF-8 ç¼–ç 的基础支æŒã€‚
所有的函数都放在表 utf8 ä¸ã€‚
æ¤åº“ä¸æä¾›é™¤ç¼–ç 处ç†ä¹‹å¤–的任何 Unicode 支æŒã€‚
所有需è¦äº†è§£å—符å«ä¹‰çš„æ“ä½œï¼Œæ¯”å¦‚å—符分类,都ä¸åœ¨æ¤èŒƒç•´ã€‚
除éžå¦æœ‰è¯´æ˜Žï¼Œ 当一个函数需è¦ä¸€ä¸ªå—节ä½ç½®çš„傿•°æ—¶ï¼Œ 都å‡å®šè¿™ä¸ªä½ç½®è¦ä¹ˆä»Žå—节åºåˆ—的开始计算, è¦ä¹ˆä»Žå—ç¬¦ä¸²é•¿åº¦åŠ ä¸€çš„ä½ç½®ç®—。 å’Œå—ç¬¦ä¸²åº“ä¸€æ ·ï¼Œè´Ÿçš„ç´¢å¼•ä»Žå—符串末尾计起。
utf8.char (···)
utf8.charpattern[\0-\x7F\xC2-\xF4][\x80-\xBF]*"
(å‚è§ §6.4.1)。
它å‡å®šå¤„ç†çš„å¯¹è±¡æ˜¯ä¸€ä¸ªåˆæ³•çš„ UTF-8 å—符串。
utf8.codes (s)返回一系列的值,å¯ä»¥è®©
for p, c in utf8.codes(s) do body end
è¿ä»£å‡ºå—符串 s 䏿‰€æœ‰çš„å—符。
这里的 p 是ä½ç½®ï¼ˆæŒ‰å—节数)而 c 是æ¯ä¸ªå—符的编å·ã€‚
如果处ç†åˆ°ä¸€ä¸ªä¸åˆæ³•çš„å—节åºåˆ—,将抛出一个错误。
utf8.codepoint (s [, i [, j]])s ä¸
从ä½ç½® i 到 j 间(包括两端)
所有å—符的编å·ã€‚
默认的 i 为 1 ,默认的 j 为 i。
如果碰上ä¸åˆæ³•çš„å—节åºåˆ—,抛出一个错误。
utf8.len (s [, i [, j]])s ä¸
从ä½ç½® i 到 j é—´ (包括两端)
UTF-8 å—符的个数。
默认的 i 为 1 ,默认的 j 为 -1 。
如果它找到任何ä¸åˆæ³•çš„å—节åºåˆ—,
返回å‡å€¼åŠ ä¸Šç¬¬ä¸€ä¸ªä¸åˆæ³•å—节的ä½ç½®ã€‚
utf8.offset (s, n [, i])s ä¸çš„第 n 个å—符的开始ä½ç½®ï¼ˆæŒ‰å—节数)
(从ä½ç½® i 处开始统计)。
è´Ÿ n 则å–在ä½ç½® i å‰çš„å—符。
当 n 是éžè´Ÿæ•°æ—¶ï¼Œé»˜è®¤çš„ i 是 1,
å¦åˆ™é»˜è®¤ä¸º #s + 1。
å› æ¤ï¼Œutf8.offset(s, -n) å–å—符串的倒数第
n 个å—符的ä½ç½®ã€‚
如果指定的å—符ä¸åœ¨å…¶ä¸æˆ–在结æŸç‚¹ä¹‹åŽï¼Œå‡½æ•°è¿”回 nil。
作为特例,当 n ç‰äºŽ 0 时,
æ¤å‡½æ•°è¿”å›žå«æœ‰ s 第 i å—节的那个å—符的开始ä½ç½®ã€‚
这个函数å‡å®š s æ˜¯ä¸€ä¸ªåˆæ³•çš„ UTF-8 å—符串。
这个库æä¾›äº†è¡¨å¤„ç†çš„通用函数。
所有函数都放在表 table ä¸ã€‚
è®°ä½ï¼Œæ— 论何时,若一个æ“作需è¦å–表的长度,
è¿™å¼ è¡¨å¿…é¡»æ˜¯ä¸€ä¸ªçœŸåºåˆ—,或是拥有 __len 元方法
(å‚è§ §3.4.7 )。
æ‰€æœ‰çš„å‡½æ•°éƒ½å¿½ç•¥ä¼ å…¥å‚æ•°çš„é‚£å¼ è¡¨ä¸çš„éžæ•°å—键。
table.concat (list [, sep [, i [, j]]])
æä¾›ä¸€ä¸ªåˆ—è¡¨ï¼Œå…¶æ‰€æœ‰å…ƒç´ éƒ½æ˜¯å—符串或数å—,返回å—符串
list[i]..sep..list[i+1] ··· sep..list[j]。
sep 的默认值是空串,
i 的默认值是 1 ,
j 的默认值是 #list 。
如果 i 比 j 大,返回空串。
table.insert (list, [pos,] value)
在 list çš„ä½ç½® pos 处æ’å…¥å…ƒç´ value ,
å¹¶åŽç§»å…ƒç´ list[pos], list[pos+1], ···, list[#list] 。
pos 的默认值为 #list+1 ,
å› æ¤è°ƒç”¨ table.insert(t,x) 会将 x æ’在列表 t 的末尾。
table.move (a1, f, e, t [,a2])
å°†å…ƒç´ ä»Žè¡¨ a1 移到表 a2。
这个函数åšäº†æ¬¡ç‰ä»·äºŽåŽé¢è¿™ä¸ªå¤šé‡èµ‹å€¼çš„ç‰ä»·æ“作:
a2[t],··· = a1[f],···,a1[e]。
a2 的默认值为 a1。
ç›®æ ‡åŒºé—´å¯ä»¥å’ŒæºåŒºé—´é‡å 。
索引 f å¿…é¡»æ˜¯æ£æ•°ã€‚
table.pack (···)
è¿”å›žç”¨æ‰€æœ‰å‚æ•°ä»¥é”® 1,2, ç‰å¡«å……的新表,
å¹¶å°† "n" è¿™ä¸ªåŸŸè®¾ä¸ºå‚æ•°çš„æ€»æ•°ã€‚
注æ„è¿™å¼ è¿”å›žçš„è¡¨ä¸ä¸€å®šæ˜¯ä¸€ä¸ªåºåˆ—。
table.remove (list [, pos])
移除 list ä¸ pos ä½ç½®ä¸Šçš„å…ƒç´ ï¼Œå¹¶è¿”å›žè¿™ä¸ªè¢«ç§»é™¤çš„å€¼ã€‚
当 pos 是在 1 到 #list 之间的整数时,
它å‘å‰ç§»åŠ¨å…ƒç´ ã€€list[pos+1], list[pos+2], ···, list[#list]
å¹¶åˆ é™¤å…ƒç´ list[#list]ï¼›
索引 pos å¯ä»¥æ˜¯ #list + 1 ,或在 #list 为 0 æ—¶å¯ä»¥æ˜¯ 0 ï¼›
åœ¨è¿™äº›æƒ…å†µä¸‹ï¼Œå‡½æ•°åˆ é™¤å…ƒç´ list[pos]。
pos 默认为 #list,
å› æ¤è°ƒç”¨ table.remove(l) 将移除表 l 的最åŽä¸€ä¸ªå…ƒç´ 。
table.sort (list [, comp])
在表内从 list[1] 到 list[#list] 原地
å¯¹å…¶é—´å…ƒç´ æŒ‰æŒ‡å®šæ¬¡åºæŽ’åºã€‚
如果æä¾›äº† comp ,
它必须是一个å¯ä»¥æŽ¥æ”¶ä¸¤ä¸ªåˆ—è¡¨å†…å…ƒç´ ä¸ºå‚æ•°çš„函数。
å½“ç¬¬ä¸€ä¸ªå…ƒç´ éœ€è¦æŽ’åœ¨ç¬¬äºŒä¸ªå…ƒç´ ä¹‹å‰æ—¶ï¼Œè¿”回真
ï¼ˆå› æ¤ not comp(list[i+1],list[i]) 在排åºç»“æŸåŽå°†ä¸ºçœŸï¼‰ã€‚
如果没有æä¾› comp,
å°†ä½¿ç”¨æ ‡å‡† Lua æ“作 < 作为替代å“。
排åºç®—法并ä¸ç¨³å®šï¼› å³å½“ä¸¤ä¸ªå…ƒç´ æ¬¡åºç›¸ç‰æ—¶ï¼Œå®ƒä»¬åœ¨æŽ’åºåŽçš„相对ä½ç½®å¯èƒ½ä¼šæ”¹å˜ã€‚
table.unpack (list [, i [, j]])返回列表ä¸çš„å…ƒç´ ã€‚ 这个函数ç‰ä»·äºŽ
return list[i], list[i+1], ···, list[j]
i 默认为 1 ,j 默认为 #list。
这个库æä¾›äº†åŸºæœ¬çš„æ•°å¦å‡½æ•°ã€‚
所以函数都放在表 math ä¸ã€‚
注解有 "integer/float" çš„å‡½æ•°ä¼šå¯¹æ•´æ•°å‚æ•°è¿”回整数结果,
对浮点(或混åˆï¼‰å‚数返回浮点结果。
圆整函数(math.ceil, math.floor, math.modf)
在结果在整数范围内时返回整数,å¦åˆ™è¿”回浮点数。
math.abs (x)
返回 x çš„ç»å¯¹å€¼ã€‚(integer/float)
math.acos (x)
返回 x çš„å余弦值(用弧度表示)。
math.asin (x)
返回 x çš„åæ£å¼¦å€¼ï¼ˆç”¨å¼§åº¦è¡¨ç¤ºï¼‰ã€‚
math.atan (y [, x])
返回 y/x çš„åæ£åˆ‡å€¼ï¼ˆç”¨å¼§åº¦è¡¨ç¤ºï¼‰ã€‚
å®ƒä¼šä½¿ç”¨ä¸¤ä¸ªå‚æ•°çš„ç¬¦å·æ¥æ‰¾åˆ°ç»“æžœè½åœ¨å“ªä¸ªè±¡é™ä¸ã€‚
(å³ä½¿ x 为零时,也å¯ä»¥æ£ç¡®çš„处ç†ã€‚)
默认的 x 是 1 ,
å› æ¤è°ƒç”¨ math.atan(y) 将返回
y çš„åæ£åˆ‡å€¼ã€‚
math.ceil (x)
返回ä¸å°äºŽ x çš„æœ€å°æ•´æ•°å€¼ã€‚
math.cos (x)
返回 x 的余弦(å‡å®šå‚数是弧度)。
math.deg (x)
将角 x 从弧度转æ¢ä¸ºè§’度。
math.exp (x)
返回 ex 的值
(e 为自然对数的底)。
math.floor (x)
返回ä¸å¤§äºŽ x 的最大整数值。
math.fmod (x, y)
返回 x 除以 y,将商å‘零圆整åŽçš„余数。
(integer/float)
math.huge
浮点数 HUGE_VAL,
这个数比任何数å—值都大。
math.log (x [, base])
返回以指定底的 x 的对数。
默认的 base 是 e
ï¼ˆå› æ¤æ¤å‡½æ•°è¿”回 x 的自然对数)。
math.max (x, ···)
è¿”å›žå‚æ•°ä¸æœ€å¤§çš„值,
大å°ç”± Lua æ“作 < 决定。
(integer/float)
math.maxinteger
math.min (x, ···)
è¿”å›žå‚æ•°ä¸æœ€å°çš„值,
大å°ç”± Lua æ“作 < 决定。
(integer/float)
math.mininteger
math.modf (x)
返回 x çš„æ•´æ•°éƒ¨åˆ†å’Œå°æ•°éƒ¨åˆ†ã€‚
第二个结果一定是浮点数。
math.piπ 的值。
math.rad (x)
将角 x 从角度转æ¢ä¸ºå¼§åº¦ã€‚
math.random ([m [, n]])
当ä¸å¸¦å‚数调用时,
返回一个 [0,1) åŒºé—´å†…ä¸€è‡´åˆ†å¸ƒçš„æµ®ç‚¹ä¼ªéšæœºæ•°ã€‚
当以两个整数 m 与 n 调用时,
math.random 返回一个 [m, n] 区间
å†…ä¸€è‡´åˆ†å¸ƒçš„æ•´æ•°ä¼ªéšæœºæ•°ã€‚
(值 n-m ä¸èƒ½æ˜¯è´Ÿæ•°ï¼Œä¸”必须在 Lua 整数的表示范围内。)
调用 math.random(n) ç‰ä»·äºŽ math.random(1,n)。
这个函数是对 C æä¾›çš„ä½éšæœºæ•°å‡½æ•°çš„å°è£…。 对其统计属性ä¸ä½œæ‹…ä¿ã€‚
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)
如果 x 是整数,返回 "integer",
如果它是浮点数,返回 "float",
如果 x 䏿˜¯æ•°å—,返回 nil。
math.ult (m, n)
如果整数 m å’Œ n ä»¥æ— ç¬¦å·æ•´æ•°å½¢å¼æ¯”较,
m 在 n 之下,返回布尔真å¦åˆ™è¿”回å‡ã€‚
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 æŒ‡å®šçš„æ¨¡å¼æ‰“开一个文件。
è¿”å›žæ–°çš„æ–‡ä»¶å¥æŸ„。
当出错时,返回 nil åŠ é”™è¯¯æ¶ˆæ¯ã€‚
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 æ˜¯å¦æ˜¯åˆæ³•çš„æ–‡ä»¶å¥æŸ„。
如果 obj å®ƒæ˜¯ä¸€ä¸ªæ‰“å¼€çš„æ–‡ä»¶å¥æŸ„,返回å—符串 "file"。
如果 obj 是一个关é—çš„æ–‡ä»¶å¥æŸ„,返回å—符串 "closed file"。
如果 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。
æ ¼å¼ "l" å’Œ "L" åªèƒ½ç”¨äºŽæ–‡æœ¬æ–‡ä»¶ã€‚
file:seek ([whence [, offset]])
设置åŠèŽ·å–基于文件开头处计算出的ä½ç½®ã€‚
设置的ä½ç½®ç”± offset å’Œ
whence å—符串 whence
指定的基点决定。基点å¯ä»¥æ˜¯ï¼š
set": 基点为 0 (文件开头);cur": 基点为当å‰ä½ç½®ï¼›end": 基点为文件尾;
当 seek æˆåŠŸæ—¶ï¼Œè¿”å›žæœ€ç»ˆä»Žæ–‡ä»¶å¼€å¤´è®¡ç®—èµ·çš„æ–‡ä»¶çš„ä½ç½®ã€‚
当 seek 失败时,返回 nil åŠ ä¸Šä¸€ä¸ªé”™è¯¯æè¿°å—符串。
whence 的默认值是 "cur",
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 åŠ é”™è¯¯æè¿°å—符串。
这个库都通过表 os 实现。
os.clock ()返回程åºä½¿ç”¨çš„æŒ‰ç§’计 CPU 时间的近似值。
os.date ([format [, time]])
è¿”å›žä¸€ä¸ªåŒ…å«æ—¥æœŸåŠæ—¶åˆ»çš„å—符串或表。
æ ¼å¼åŒ–方法å–决于所给å—符串 format。
如果æä¾›äº† time 傿•°ï¼Œ
æ ¼å¼åŒ–这个时间
(这个值的å«ä¹‰å‚è§ os.time 函数)。
å¦åˆ™ï¼Œdate æ ¼å¼åŒ–当剿—¶é—´ã€‚
如果 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 以å—符串形å¼è¿”回,
æ ¼å¼åŒ–方法éµå¾ª ISO C 函数 strftime 的规则。
如果ä¸ä¼ 傿•°è°ƒç”¨ï¼Œ
date 返回一个åˆç†çš„æ—¥æœŸæ—¶é—´ä¸²ï¼Œ
æ ¼å¼å–决于宿主程åºä»¥åŠå½“å‰çš„区域设置
(å³ï¼Œos.date() ç‰ä»·äºŽ os.date("%c"))。
åœ¨éž POSIX 系统上,
由于这个函数ä¾èµ– C 函数 gmtime å’Œ localtime,
它å¯èƒ½å¹¶éžçº¿ç¨‹å®‰å…¨çš„。
os.difftime (t2, t1)
返回以秒计算的时刻 t1 到 t2 的差值。
(这里的时刻是由 os.time 返回的值)。
在 POSIX,Windows,和其它一些系统ä¸ï¼Œè¿™ä¸ªå€¼å°±ç‰äºŽ
t2-t1。
os.execute ([command])
这个函数ç‰ä»·äºŽ ISO C 函数 system。
它调用系统解释器执行 command。
如果命令æˆåŠŸè¿è¡Œå®Œæ¯•,第一个返回值就是 true,
å¦åˆ™æ˜¯ nil。
在第一个返回值之åŽï¼Œå‡½æ•°è¿”回一个å—ç¬¦ä¸²åŠ ä¸€ä¸ªæ•°å—。如下:
exit":
命令æ£å¸¸ç»“æŸï¼›
接下æ¥çš„æ•°å—是命令的退出状æ€ç 。
signal":
å‘½ä»¤è¢«ä¿¡å·æ‰“æ–ï¼›
接下æ¥çš„æ•°å—是打æ–该命令的信å·ã€‚
如果ä¸å¸¦å‚数调用,
os.execute 在系统解释器å˜åœ¨çš„æ—¶å€™è¿”回真。
os.exit ([code [, close]])
调用 ISO C 函数 exit 终æ¢å®¿ä¸»ç¨‹åºã€‚
如果 code 为 true,
返回的状æ€ç 是 EXIT_SUCCESSï¼›
如果 code 为 false,
返回的状æ€ç 是 EXIT_FAILUREï¼›
如果 code 是一个数å—,
返回的状æ€ç 就是这个数å—。
code 的默认值为 true。
如果第二个å¯é€‰å‚æ•° close 为真,
在退出å‰å…³é— Lua çŠ¶æ€æœºã€‚
os.getenv (varname)
返回进程环境å˜é‡ varname 的值,
如果该å˜é‡æœªå®šä¹‰ï¼Œè¿”回 nil 。
os.remove (filename)åˆ é™¤æŒ‡å®šåå—的文件(在 POSIX 系统上å¯ä»¥æ˜¯ä¸€ä¸ªç©ºç›®å½•) 如果函数失败,返回 nil åŠ ä¸€ä¸ªé”™è¯¯æè¿°ä¸²åŠå‡ºé”™ç 。
os.rename (oldname, newname)
å°†åå—为 oldname 的文件或目录更å为 newname。
如果函数失败,返回 nil
åŠ ä¸€ä¸ªé”™è¯¯æè¿°ä¸²åŠå‡ºé”™ç 。
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 函数。
返回值是一个å«ä¹‰ç”±ä½ 的系统决定的数å—。
在 POSIX,Windows,和其它一些系统ä¸ï¼Œ
这个数å—统计了从指定时间("epoch")开始ç»åŽ†çš„ç§’æ•°ã€‚
对于å¦å¤–的系统,其å«ä¹‰æœªå®šä¹‰ï¼Œ
ä½ åªèƒ½æŠŠ time 的返回数å—用于
os.date 和 os.difftime
çš„å‚æ•°ã€‚
os.tmpname ()返回一个å¯ç”¨äºŽä¸´æ—¶æ–‡ä»¶çš„æ–‡ä»¶åå—符串。 这个文件在使用å‰å¿…é¡»æ˜¾å¼æ‰“开,ä¸å†ä½¿ç”¨æ—¶éœ€è¦æ˜¾å¼åˆ 除。
在 POSIX 系统上, è¿™ä¸ªå‡½æ•°ä¼šä»¥æ¤æ–‡ä»¶å创建一个文件以回é¿å®‰å…¨é£Žé™©ã€‚ (别人å¯èƒ½æœªç»å…许在获å–到这个文件ååˆ°åˆ›å»ºè¯¥æ–‡ä»¶ä¹‹é—´çš„æ—¶åˆ»åˆ›å»ºæ¤æ–‡ä»¶ã€‚) ä½ ä¾æ—§éœ€è¦åœ¨ä½¿ç”¨å®ƒçš„æ—¶å€™å…ˆæ‰“开,并最åŽåˆ 除(å³ä½¿ä½ 没使用到)。
åªæœ‰æœ‰å¯èƒ½ï¼Œä½ 更应该使用
io.tmpfile,
å› ä¸ºè¯¥æ–‡ä»¶å¯ä»¥åœ¨ç¨‹åºç»“æŸæ—¶è‡ªåŠ¨åˆ é™¤ã€‚
这个库æä¾›äº† Lua 程åºè°ƒè¯•接å£ï¼ˆ§4.9)的功能。 å…¶ä¸ä¸€äº›å‡½æ•°è¿å了 Lua 代ç 的基本å‡å®š (例如,ä¸ä¼šä»Žå‡½æ•°ä¹‹å¤–访问函数的局部å˜é‡ï¼› 用户数æ®çš„元表ä¸ä¼šè¢« Lua 代ç 修改; Lua 程åºä¸ä¼šå´©æºƒï¼‰ï¼Œ å› æ¤å®ƒä»¬æœ‰å¯èƒ½å±å®³åˆ°å…¶å®ƒä»£ç 的安全性。 æ¤å¤–,库里的一些函数å¯èƒ½è¿è¡Œçš„很慢。
这个库里的所有函数都æä¾›åœ¨è¡¨ debug 内。
所有æ“作线程的函数,å¯é€‰çš„ç¬¬ä¸€ä¸ªå‚æ•°éƒ½æ˜¯é’ˆå¯¹çš„线程。
默认值永远是当å‰çº¿ç¨‹ã€‚
debug.debug ()
进入一个用户交互模å¼ï¼Œè¿è¡Œç”¨æˆ·è¾“入的æ¯ä¸ªå—符串。
使用简å•的命令以åŠå…¶å®ƒè°ƒè¯•设置,用户å¯ä»¥æ£€é˜…全局å˜é‡å’Œå±€éƒ¨å˜é‡ï¼Œ
改å˜å˜é‡çš„值,计算一些表达å¼ï¼Œç‰ç‰ã€‚
è¾“å…¥ä¸€è¡Œä»…åŒ…å« cont çš„å—符串将结æŸè¿™ä¸ªå‡½æ•°ï¼Œ
è¿™æ ·è°ƒç”¨è€…å°±å¯ä»¥ç»§ç»å‘下è¿è¡Œã€‚
注æ„,debug.debug 输入的命令在文法上并没有内嵌到任何函数ä¸ï¼Œ
å› æ¤ä¸èƒ½ç›´æŽ¥åŽ»è®¿é—®å±€éƒ¨å˜é‡ã€‚
debug.gethook ([thread])
返回三个表示线程钩å设置的值:
当å‰é’©å函数,当å‰é’©å掩ç ,当å‰é’©å计数
(debug.sethook 设置的那些)。
debug.getinfo ([thread,] f [, what])
返回关于一个函数信æ¯çš„表。
ä½ å¯ä»¥ç›´æŽ¥æä¾›è¯¥å‡½æ•°ï¼Œ
也å¯ä»¥ç”¨ä¸€ä¸ªæ•°å— f 表示该函数。
æ•°å— f 表示è¿è¡Œåœ¨æŒ‡å®šçº¿ç¨‹çš„è°ƒç”¨æ ˆå¯¹åº”å±‚æ¬¡ä¸Šçš„å‡½æ•°ï¼š
0 层表示当å‰å‡½æ•°ï¼ˆgetinfo 自身);
1 层表示调用 getinfo 的函数
ï¼ˆé™¤éžæ˜¯å°¾è°ƒç”¨ï¼Œè¿™ç§æƒ…况ä¸è®¡å…¥æ ˆï¼‰ï¼›ç‰ç‰ã€‚
如果 f 是一个比活动函数数é‡è¿˜å¤§çš„æ•°å—,
getinfo 返回 nil。
åªæœ‰å—符串 what 䏿œ‰æè¿°è¦å¡«å……哪些项,
返回的表å¯ä»¥åŒ…å« lua_getinfo 能返回的所有项。
what 默认是返回æä¾›çš„é™¤åˆæ³•行å·è¡¨å¤–的所有信æ¯ã€‚
对于选项 'f' ,会在å¯èƒ½çš„æƒ…况下,增åŠ
func 域ä¿å˜å‡½æ•°è‡ªèº«ã€‚
对于选项 'L' ,会在å¯èƒ½çš„æƒ…况下,增åŠ
activelines 域ä¿å˜åˆæ³•行å·è¡¨ã€‚
例如,è¡¨è¾¾å¼ debug.getinfo(1,"n")
返回带有当å‰å‡½æ•°åå—ä¿¡æ¯çš„表(如果找的到åå—çš„è¯ï¼‰ï¼Œ
è¡¨è¾¾å¼ debug.getinfo(print)
返回关于 print 函数的
åŒ…å«æœ‰æ‰€æœ‰èƒ½æä¾›ä¿¡æ¯çš„表。
debug.getlocal ([thread,] f, local)
æ¤å‡½æ•°è¿”å›žåœ¨æ ˆçš„ f 层处函数的索引为 local 的局部å˜é‡
çš„åå—和值。
这个函数ä¸ä»…用于访问显å¼å®šä¹‰çš„局部å˜é‡ï¼Œä¹ŸåŒ…括形å‚ã€ä¸´æ—¶å˜é‡ç‰ã€‚
ç¬¬ä¸€ä¸ªå½¢å‚æˆ–是定义的第一个局部å˜é‡çš„索引为 1 ,
ç„¶åŽéµå¾ªåœ¨ä»£ç ä¸å®šä¹‰æ¬¡åºï¼Œä»¥æ¬¡ç±»æŽ¨ã€‚
å…¶ä¸åªè®¡ç®—函数当å‰ä½œç”¨åŸŸçš„æ´»åЍå˜é‡ã€‚
负索引指å¯å˜å‚æ•°ï¼›
-1 指第一个å¯å˜å‚数。
如果该索引处没有å˜é‡ï¼Œå‡½æ•°è¿”回 nil。
若指定的层次越界,抛出错误。
ï¼ˆä½ å¯ä»¥è°ƒç”¨ debug.getinfo æ¥æ£€æŸ¥å±‚次是å¦åˆæ³•。)
以 '(' (开括å·ï¼‰æ‰“头的å˜é‡å表示没有åå—çš„å˜é‡
(比如是循环控制用到的控制å˜é‡ï¼Œ
或是去除了调试信æ¯çš„代ç å—)。
傿•° f 也å¯ä»¥æ˜¯ä¸€ä¸ªå‡½æ•°ã€‚
è¿™ç§æƒ…况下,getlocal 仅返回函数形å‚çš„åå—。
debug.getmetatable (value)
返回给定 value 的元表。
若其没有元表则返回 nil 。
debug.getregistry ()返回注册表(å‚è§ §4.5)。
debug.getupvalue (f, up)
æ¤å‡½æ•°è¿”回函数 f 的第 up 个上值的åå—和值。
如果该函数没有那个上值,返回 nil 。
以 '(' (开括å·ï¼‰æ‰“头的å˜é‡å表示没有åå—çš„å˜é‡
(去除了调试信æ¯çš„代ç å—)。
debug.getuservalue (u)
返回关è”在 u 上的 Lua 值。
如果 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 赋给
æ ˆä¸Šç¬¬ level 层函数的第 local 个局部å˜é‡ã€‚
如果没有那个å˜é‡ï¼Œå‡½æ•°è¿”回 nil 。
如果 level 越界,抛出一个错误。
ï¼ˆä½ å¯ä»¥è°ƒç”¨ debug.getinfo æ¥æ£€æŸ¥å±‚次是å¦åˆæ³•。)
å¦åˆ™ï¼Œå®ƒè¿”回局部å˜é‡çš„åå—。
关于å˜é‡ç´¢å¼•å’Œåå—,å‚è§ debug.getlocal。
debug.setmetatable (value, table)
å°† value 的元表设为 table (å¯ä»¥æ˜¯ nil)。
返回 value。
debug.setupvalue (f, up, value)
这个函数将 value 设为函数 f 的第
up 个上值。
如果函数没有那个上值,返回 nil
å¦åˆ™ï¼Œè¿”回该上值的åå—。
debug.setuservalue (udata, value)
å°† value 设为 udata 的关è”值。
udata 必须是一个完全用户数æ®ã€‚
返回 udata。
debug.traceback ([thread,] [message [, level]])
如果 message æœ‰ï¼Œä¸”ä¸æ˜¯å—符串或 nil,
函数ä¸åšä»»ä½•处ç†ç›´æŽ¥è¿”回 message。
å¦åˆ™ï¼Œå®ƒè¿”å›žè°ƒç”¨æ ˆçš„æ ˆå›žæº¯ä¿¡æ¯ã€‚
å—符串å¯é€‰é¡¹ message è¢«æ·»åŠ åœ¨æ ˆå›žæº¯ä¿¡æ¯çš„开头。
æ•°å—å¯é€‰é¡¹ level æŒ‡æ˜Žä»Žæ ˆçš„å“ªä¸€å±‚å¼€å§‹å›žæº¯
(默认为 1 ,å³è°ƒç”¨ traceback 的那里)。
debug.upvalueid (f, n)
返回指定函数第 n
ä¸ªä¸Šå€¼çš„å”¯ä¸€æ ‡è¯†ç¬¦ï¼ˆä¸€ä¸ªè½»é‡ç”¨æˆ·æ•°æ®ï¼‰ã€‚
è¿™ä¸ªå”¯ä¸€æ ‡è¯†ç¬¦å¯ä»¥è®©ç¨‹åºæ£€æŸ¥ä¸¤ä¸ªä¸åŒçš„é—包是å¦å…±äº«äº†ä¸Šå€¼ã€‚ è‹¥ Lua é—包之间共享的是åŒä¸€ä¸ªä¸Šå€¼ ï¼ˆå³æŒ‡å‘一个外部局部å˜é‡ï¼‰ï¼Œä¼šè¿”回相åŒçš„æ ‡è¯†ç¬¦ã€‚
debug.upvaluejoin (f1, n1, f2, n2)
让 Lua é—包 f1 的第 n1 个上值
引用 Lua é—包 f2 的第 n2 个上值。
虽然 Lua 被设计æˆä¸€é—¨æ‰©å±•å¼è¯è¨€ï¼Œç”¨äºŽåµŒå…¥ä¸€ä¸ªå®¿ä¸»ç¨‹åºã€‚
但ç»å¸¸ä¹Ÿä¼šè¢«å½“æˆç‹¬ç«‹è¯è¨€ä½¿ç”¨ã€‚
独立版的 Lua è¯è¨€è§£é‡Šå™¨éšæ ‡å‡†åŒ…å‘å¸ƒï¼Œå°±å« lua。
独立版解释器ä¿ç•™äº†æ‰€æœ‰çš„æ ‡å‡†åº“åŠè°ƒè¯•库。
其命令行用法为:
lua [options] [script [args]]
选项有:
-e stat: 执行一段å—符串 stat ï¼›-l mod: “请求模å—†mod ï¼›-i: 在è¿è¡Œå®Œ 脚本 åŽè¿›å…¥äº¤äº’模å¼ï¼›-v: 打å°ç‰ˆæœ¬ä¿¡æ¯ï¼›-E: 忽略环境å˜é‡ï¼›--: 䏿¢å¯¹åŽé¢é€‰é¡¹çš„处ç†ï¼›-: 把 stdin 当作一个文件è¿è¡Œï¼Œå¹¶ä¸æ¢å¯¹åŽé¢é€‰é¡¹çš„处ç†ã€‚
在处ç†å®Œé€‰é¡¹åŽï¼Œlua è¿è¡ŒæŒ‡å®šçš„ 脚本。
如果ä¸å¸¦å‚数调用,
åœ¨æ ‡å‡†è¾“å…¥ï¼ˆstdin)是终端时,lua 的行为和 lua -v -i 相åŒã€‚
å¦åˆ™ç›¸å½“于 lua - 。
如果调用时ä¸å¸¦é€‰é¡¹ -E,
解释器会在è¿è¡Œä»»ä½•傿•°å‰ï¼Œæ£€æŸ¥çŽ¯å¢ƒå˜é‡ LUA_INIT_5_3
ï¼ˆæˆ–åœ¨ç‰ˆæœ¬åæœªå®šä¹‰æ—¶ï¼Œæ£€æŸ¥ LUA_INIT )。
如果该å˜é‡å†…å˜æ ¼å¼ä¸º @filename,
lua 执行该文件。
å¦åˆ™ï¼Œlua 执行该å—符串。
如果调用时有选项 -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 å¹¶ä¸å¸¦å‚数。
(这里的 $ 是命令行æç¤ºã€‚ä½ çš„å‘½ä»¤è¡Œæç¤ºå¯èƒ½ä¸ä¸€æ ·ã€‚)
在è¿è¡Œä»»ä½•代ç å‰ï¼Œ
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 所有的代ç å—ä¸€æ ·ï¼Œ
脚本被编译æˆä¸€ä¸ªå¯å˜å‚数函数。)
在交互模å¼ä¸‹ï¼Œ Lua 䏿–的显示æç¤ºç¬¦ï¼Œå¹¶ç‰å¾…下一行输入。 一旦读到一行, é¦–å…ˆè¯•ç€æŠŠè¿™è¡Œè§£é‡Šä¸ºä¸€ä¸ªè¡¨è¾¾å¼ã€‚ 如果æˆåŠŸè§£é‡Šï¼Œå°±æ‰“å°è¡¨è¾¾å¼çš„值。 å¦åˆ™ï¼Œå°†è¿™è¡Œè§£é‡Šä¸ºè¯å¥ã€‚ å¦‚æžœä½ å†™äº†ä¸€è¡Œæœªå®Œæˆçš„è¯å¥ï¼Œ 解释器会用一个ä¸åŒçš„æç¤ºç¬¦æ¥ç‰å¾…ä½ å†™å®Œã€‚
当脚本ä¸å‡ºçŽ°äº†æœªä¿æŠ¤çš„é”™è¯¯ï¼Œ
è§£é‡Šå™¨å‘æ ‡å‡†é”™è¯¯æµæŠ¥å‘Šé”™è¯¯ã€‚
如果错误对象并éžä¸€ä¸ªå—ç¬¦ä¸²ï¼Œä½†æ˜¯å´æœ‰å…ƒæ–¹æ³•
__tostring çš„è¯ï¼Œ
è§£é‡Šå™¨ä¼šè°ƒç”¨è¿™ä¸ªå…ƒæ–¹æ³•ç”Ÿæˆæœ€ç»ˆçš„æ¶ˆæ¯ã€‚
å¦åˆ™ï¼Œè§£é‡Šå™¨å°†é”™è¯¯å¯¹è±¡è½¬æ¢ä¸ºä¸€ä¸ªå—ç¬¦ä¸²ï¼Œå¹¶æŠŠæ ˆå›žæº¯ä¿¡æ¯åŠ åœ¨å‰é¢ã€‚
如果æ£å¸¸ç»“æŸè¿è¡Œï¼Œ
解释器会关é—主 Lua çŠ¶æ€æœº
(å‚è§ lua_close)。
脚本å¯ä»¥é€šè¿‡è°ƒç”¨
os.exit
æ¥ç»“æŸï¼Œä»¥å›žé¿è¿™ä¸ªæ¥éª¤ã€‚
为了让 Lua å¯ä»¥ç”¨äºŽ Unix 系统的脚本解释器。
独立版解释器会忽略代ç å—的以 # 打头的第一行。
å› æ¤ï¼ŒLua 脚本å¯ä»¥é€šè¿‡
chmod +x ä»¥åŠ #! å½¢å¼å˜æˆä¸€ä¸ªå¯æ‰§è¡Œæ–‡ä»¶ã€‚
ç±»ä¼¼è¿™æ ·
#!/usr/local/bin/lua
(当然,
Lua 解释器的ä½ç½®å¯¹äºŽä½ 的机器æ¥è¯´å¯èƒ½ä¸ä¸€æ ·ã€‚
如果 lua åœ¨ä½ çš„ PATH ä¸ï¼Œ
写æˆ
#!/usr/bin/env lua
更为通用。)
这里我们列出了把程åºä»Ž Lua 5.2 è¿ç§»åˆ° Lua 5.3 会碰到的ä¸å…¼å®¹çš„地方。
ä½ å¯ä»¥åœ¨ç¼–译 Lua 时定义一些æ°å½“的选项(å‚è§æ–‡ä»¶ luaconf.h),
æ¥å›žé¿ä¸€äº›ä¸å…¼å®¹æ€§ã€‚
然而,这些兼容选项以åŽä¼šç§»é™¤ã€‚
Lua 的版本更替总是会修改一些 C API å¹¶æ¶‰åŠæºä»£ç 的改å˜ã€‚ 例如一些常é‡çš„æ•°å—å€¼ï¼Œç”¨å®æ¥å®žçŽ°ä¸€äº›å‡½æ•°ã€‚ å› æ¤ï¼Œä½ ä¸èƒ½å‡è®¾åœ¨ä¸åŒçš„ Lua 版本间å¯ä»¥åšåˆ°äºŒè¿›åˆ¶å…¼å®¹ã€‚ å½“ä½ ä½¿ç”¨æ–°ç‰ˆæ—¶ï¼Œä¸€å®šè¦å°†ä½¿ç”¨äº† Lua API 的客户程åºé‡æ–°ç¼–译。
åŒæ ·ï¼ŒLua 版本更替还会改å˜é¢„编译代ç å—的内部呈现方å¼ï¼› 在ä¸åŒçš„ Lua 版本间,预编译代ç å—ä¸å…¼å®¹ã€‚
官方å‘å¸ƒç‰ˆçš„æ ‡å‡†è·¯å¾„ä¹Ÿå¯èƒ½éšç‰ˆæœ¬å˜åŒ–。
ä½ å¯ä»¥é€šè¿‡æŠŠæ•°å—都强制转æ¢ä¸ºæµ®ç‚¹æ•°æ¥æ¶ˆé™¤å·®å¼‚
(在 Lua 5.2 ä¸ï¼Œæ‰€æœ‰çš„æ•°å—都是浮点数)。
æ¯”å¦‚ä½ å¯ä»¥å°†æ‰€æœ‰çš„常é‡éƒ½ä»¥ .0 结尾,
或是使用 x = x + 0.0 æ¥è½¬æ¢ä¸€ä¸ªå˜é‡ã€‚
(这æ¡å»ºè®®ä»…用于å¶å°”快速解决一些ä¸å…¼å®¹é—®é¢˜ï¼›
è¿™ä¸æ˜¯ä¸€æ¡å¥½çš„编程准则。
好好写程åºçš„è¯ï¼Œä½ 应该在需è¦ä½¿ç”¨æµ®ç‚¹æ•°çš„地方用浮点数,
éœ€è¦æ•´æ•°çš„地方用整数。)
.0 åŽç¼€ã€‚
(例如,浮点数 2.0 ä¼šè¢«æ‰“å°æˆ 2.0,
è€Œä¸æ˜¯ 2。)
å¦‚æžœä½ éœ€è¦å®šåˆ¶æ•°å—çš„æ ¼å¼ï¼Œå°±å¿…须显å¼çš„æ ¼å¼åŒ–它们。
ï¼ˆå‡†ç¡®è¯´è¿™ä¸ªä¸æ˜¯å…¼å®¹æ€§é—®é¢˜ï¼Œ å› ä¸º Lua 并没有规定数å—å¦‚ä½•æ ¼å¼åŒ–æˆå—符串, 但一些程åºå‡å®šéµå¾ªæŸç§ç‰¹åˆ«çš„æ ¼å¼ã€‚)
bit32 库废弃了。
使用一个外部兼容库很容易,
ä¸è¿‡æœ€å¥½ç›´æŽ¥ç”¨å¯¹åº”çš„ä½æ“ä½œç¬¦æ¥æ›¿æ¢å®ƒã€‚
ï¼ˆæ³¨æ„ bit32 åªèƒ½é’ˆå¯¹ 32 使•´æ•°è¿ç®—,
è€Œæ ‡å‡† Lua ä¸çš„使“作å¯ä»¥ç”¨äºŽ 64 使•´æ•°ã€‚)
ipairs 这个è¿ä»£å™¨ä¹Ÿä¼šè€ƒè™‘元方法,而 __ipairs 元方法被废弃了。
io.read 的选项åä¸å†ç”¨ '*' 打头。
但出于兼容性考虑,Lua 会继ç»å¿½ç•¥æŽ‰è¿™ä¸ªå—符。
atan2, cosh, sinh, tanh, pow,
frexp, ä»¥åŠ ldexp 。
ä½ å¯ä»¥ç”¨ x^y æ›¿æ¢ math.pow(x,y)ï¼›
ä½ å¯ä»¥ç”¨ math.atan æ›¿æ¢ math.atan2,å‰è€…现在å¯ä»¥æŽ¥æ”¶ä¸€æˆ–ä¸¤ä¸ªå‚æ•°ï¼›
ä½ å¯ä»¥ç”¨ x * 2.0^exp æ›¿æ¢ math.ldexp(x,exp)。
若用到其它æ“ä½œï¼Œä½ å¯ä»¥å†™ä¸€ä¸ªæ‰©å±•库,或在 Lua ä¸å®žçŽ°å®ƒä»¬ã€‚
require 在æœç´¢ C åŠ è½½å™¨æ—¶å¤„ç†ç‰ˆæœ¬å·çš„æ–¹å¼æœ‰æ‰€å˜åŒ–。
现在,版本å·åº”该跟在模å—ååŽï¼ˆå…¶å®ƒå¤§å¤šæ•°å·¥å…·éƒ½æ˜¯è¿™æ ·å¹²çš„)。
å‡ºäºŽå…¼å®¹æ€§è€ƒè™‘ï¼Œå¦‚æžœä½¿ç”¨æ–°æ ¼å¼æ‰¾ä¸åˆ°åŠ è½½å™¨çš„è¯ï¼Œæœç´¢å™¨ä¾ç„¶ä¼šå°è¯•æ—§æ ¼å¼ã€‚
(Lua 5.2 å·²ç»æ˜¯è¿™æ ·å¤„ç†äº†ï¼Œä½†æ˜¯å¹¶æ²¡æœ‰å†™åœ¨æ–‡æ¡£é‡Œã€‚)
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)。
这是一份采用扩展 BNF æè¿°çš„ Lua å®Œæ•´è¯æ³•。 在扩展 BNF ä¸ï¼Œ {A} 表示 0 或多个 A , [A] 表示一个å¯é€‰çš„ A 。 (æ“作符优先级,å‚è§ §3.4.8ï¼› 对于最终符å·ï¼Œåå—,数å—,å—符串å—é¢é‡çš„解释,å‚è§ §3.1。)
chunk ::= block
block ::= {stat} [retstat]
stat ::= ‘;’ |
varlist ‘=’ explist |
functioncall |
label |
break |
goto Name |
do block end |
while exp do block end |
repeat block until exp |
if exp then block {elseif exp then block} [else block] end |
for Name ‘=’ exp ‘,’ exp [‘,’ exp] do block end |
for namelist in explist do block end |
function funcname funcbody |
local function Name funcbody |
local namelist [‘=’ explist]
retstat ::= return [explist] [‘;’]
label ::= ‘::’ Name ‘::’
funcname ::= Name {‘.’ Name} [‘:’ Name]
varlist ::= var {‘,’ var}
var ::= Name | prefixexp ‘[’ exp ‘]’ | prefixexp ‘.’ Name
namelist ::= Name {‘,’ Name}
explist ::= exp {‘,’ exp}
exp ::= nil | false | true | Numeral | LiteralString | ‘...’ | functiondef |
prefixexp | tableconstructor | exp binop exp | unop exp
prefixexp ::= var | functioncall | ‘(’ exp ‘)’
functioncall ::= prefixexp args | prefixexp ‘:’ Name args
args ::= ‘(’ [explist] ‘)’ | tableconstructor | LiteralString
functiondef ::= function funcbody
funcbody ::= ‘(’ [parlist] ‘)’ block end
parlist ::= namelist [‘,’ ‘...’] | ‘...’
tableconstructor ::= ‘{’ [fieldlist] ‘}’
fieldlist ::= field {fieldsep field} [fieldsep]
field ::= ‘[’ exp ‘]’ ‘=’ exp | Name ‘=’ exp | exp
fieldsep ::= ‘,’ | ‘;’
binop ::= ‘+’ | ‘-’ | ‘*’ | ‘/’ | ‘//’ | ‘^’ | ‘%’ |
‘&’ | ‘~’ | ‘|’ | ‘>>’ | ‘<<’ | ‘..’ |
‘<’ | ‘<=’ | ‘>’ | ‘>=’ | ‘==’ | ‘~=’ |
and | or
unop ::= ‘-’ | not | ‘#’ | ‘~’