在 Lua 中,Light userdata 是一種使用者資料,而使用者資料又屬於基本資料類型之一 [1]。與 Heavy userdata 相同的地方是,二者的特徵如下:
- Light userdata 和 Heavy userdata 的名稱容易混淆,且二者都具備
type(x) == 'userdata'
的屬性,但二者的行為卻有很大差異 [1],如下所述。 - Light userdatum 代表指向實體記憶位址的單一指標 (void *),通常是 32 或 64 位元的數值,視不同的平台而定。Light userdata 的目的是在 Lua 中儲存 C 指標 (注意:視不同平台的資料類型而定,Lua 的數字是否適合這項用途,則不確定)。
- Heavy userdatum 代表 Lua 記憶體中配置與管理的 (垃圾回收的) 可變動的位元組區域。在 Lua 中,只有這部分記憶體允許使用 C 語言 (透過 userdata 的指標) 直接讀取/寫入,而無須使用 C API。
- Light userdata 的語意為值,而 Heavy userdata 的語意為物件。物件具有獨特的識別碼 [2]:使用相同資料建構的兩個 Heavy userdata 將始終與眾不同 (例如:
rawequal
會以記憶位址來區分;反之,使用相同資料建構的兩個 Light userdata 將永遠無法區分,因為它們是透過值而非位址來比較。) - Light userdata (與 Heavy userdata 不同) 不是垃圾回收的。[LuaImplementations] 一般會在單一暫存器中配置每個 light userdatum,且以值的方式複製,而 Heavy userdata 則會在堆積中配置,並透過參照 (指標) 傳遞。
- 等同性:如果
x
是 lightuserdatum,則 x == y
的結果為真且僅在 y
也是代表相同指標的 light userdatum 時成立。Light userdata 可用作表格金鑰,在此情況下,x == y
表示 t[x]
和 t[y]
指涉相同的表格值 (但不表示 t[x] == t[y]
,因為 NaN ~= NaN)。__eq
元方法對 light userdata 無效 (注意:手冊未在此部分說明清楚 [1])。 - Light userdata (與 Heavy userdata 不同) 沒有每個值都異動的元表格。所有 light userdata 共用相同的元表格,預設情況下並未設定 (
nil
)。 -
tostring(x)
一般會以十六進位符號顯示指標,雖然這只是 [LuaImplementations] 的特定用法。
某些有趣之處
- 將 C 指標對應至 Lua 值的常見技巧,是以該指標的 light userdata 當作註冊表中的金鑰。[Reference Manual, 3.5]。請謹記,這些對應並不會自動垃圾回收 [3],因此你可能希望使用弱化表格,而不是註冊表 (註冊表預設情況下並非弱化,但可以將弱化表格儲存在其中)。
- 有些人表示使用 lightuserdata 不只是指標,而是一個句柄 [4]。也可以在其中表示其他資料 [5]。小心不要混合指標和非指標使用者資料,以免造成衝突(例如同時將兩者儲存在註冊表中)。
- Light userdata 是透過 C API 使用 [lua_pushlightuserdata] 建立的。預設情況下,Lua 無法使用 Lua 建立 lightuserdata。
- 可以在 [1] 中找到 light userdata 的一頁摘要。
--DavidManura
另請參閱
- [1] ProgrammingInLua?,章節 28.5「Light Userdata」。
最新變更 · 喜好設定
編輯 · 歷程記錄
最後於 2011 年 8 月 4 日凌晨 3:56 GMT 編輯 (diff)