Lua 虚拟化

lua-users home
wiki

在 Lua 语言中,值只是部分“可虚拟化”的。这里,可虚拟化意味着任何具有元表的对象(表或用户数据)都可以像其他类型的值一样工作,包括内置类型。

以下是 Lua (5.1) 接近可虚拟化的总结

   Operation           Example             Works?     Metamethods/comments
   ---------           -------             ------     --------------------
Numbers
   Arithmetic          a + b               Yes        __add, __sub, __mul, __div, __pow, __unm
   Equality            a == b              Limited[*] __eq
   Ordering            a < b               Limited[*] __lt, __le

Booleans
   Truth value         if a then           No         Would add overhead to the idiom 'if table[key] then'
   Boolean Logic       not a, a and b      No

Strings
   Concatenation       a .. b              Yes        __concat  (see below)
   Get length          string.len(a)       No[!]
   Other utility       string.find, etc.   No[!]

Tables
   Indexing            a[b]                Yes        __index
   Write to index      a[b] = c            Yes        __newindex
   Length              #a                  Mostly     __len (but requires userdata before 5.2)
   Iterating           for x in pairs(a)   No         Fix is trivial [#]
   raw operations      rawget(a,k)         No
   array functions     table.insert(a,b)   No

Functions
   Invoking            a(x, y)             Yes        __call [+]
   
Threads
   Resuming            coroutine.resume(a) No[!]

File handles           io.type(a), ...     No[!]      See also I/O library abstraction [@]

Misc
   String repr.        tostring(a)         Limited    __tostring (not honored by C lua_tostring)
   type function       type(a)             No

[*] Lua 定义不同类型之间的相等或不等总是返回 false。__eq 元方法也总是对原始相等的值返回 true,但这不支持 NaN=0/0 值的行为,其中通常 NaN ~= NaN。

[+] Lua 中有一些地方没有检查 __call 元方法。其中之一是 __index 元方法本身(这会影响 FuncTables)。

[!] 本地类型可以有元表,允许您使用 : 符号(例如 aString:find(aPattern)),这是可虚拟化的。只有某些类型(如字符串)默认情况下定义了元表,但可以通过 debug.setmetatable 添加。

[#] 请参阅 GeneralizedPairsAndIpairs 以了解如何虚拟化 pairs/ipairs/next。另请参阅 LuaFiveTwo

[@] LuaList:2008-07/msg00345.htmlLuaList:2005-05/msg00178.html

虚拟化的优势

缺点

RiciLake 添加

注意:在 a .. b 的情况下,如果 ab 中一个是 number,另一个是具有 __concat 元方法的对象,则 number 将在调用元方法之前转换为 string。此外,.. 是右结合的,但如果 ab 都具有 __concat 元方法,则 a 具有优先级。因此,对于 a .. b .. c,其中所有三个都具有元方法,序列将为:ameta.__concat(a, bmeta.__concat(b, c))。此外,在 a .. 34 .. 56 的情况下,结果将为 ameta.__concat(a, "3456")。其中一些可能令人惊讶。

最近更改 · 偏好设置
编辑 · 历史记录
最后编辑于 2010 年 9 月 25 日凌晨 4:10 GMT (差异)