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.html, LuaList: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")。其中某些可能令人驚訝。

RecentChanges · 喜好設定
編輯 · 歷程記錄
上次編輯於 2010 年 9 月 25 日凌晨 04:10 GMT (diff)