第一版是針對 Lua 5.0 編寫的。儘管在很大程度上仍然適用於後續版本,但仍有一些差異。
第四版針對 Lua 5.3,可在 Amazon 和其他書店購買。
購買這本書,您還可以協助 支援 Lua 專案


28.5 – 輕量級使用者資料

我們到目前為止使用的使用者資料稱為完整使用者資料。Lua 提供另一種使用者資料,稱為輕量級使用者資料

輕量級使用者資料是一個表示 C 指標(即 void * 值)的值。由於它是一個值,我們不會建立它們(就像我們不會建立數字一樣)。若要將輕量級使用者資料放入堆疊中,我們使用 lua_pushlightuserdata

    void lua_pushlightuserdata (lua_State *L, void *p);

儘管名稱相同,但輕量級使用者資料與完整使用者資料有很大的不同。輕量級使用者資料不是緩衝區,而是單一指標。它們沒有元表。與數字一樣,輕量級使用者資料不需要(也不會)由垃圾收集器管理。

有些人將輕量級使用者資料用作完整使用者資料的廉價替代品。然而,這並非典型用法。首先,對於輕量級使用者資料,您必須自行管理記憶體,因為它們不受垃圾收集的約束。其次,儘管名稱如此,但完整使用者資料也很便宜。與給定記憶體大小的 malloc 相比,它們增加的開銷很小。

輕量級使用者資料的真正用途來自於相等性。由於完整使用者資料是一個物件,因此它只等於它自己。另一方面,輕量級使用者資料表示 C 指標值。因此,它等於表示相同指標的任何使用者資料。因此,我們可以使用輕量級使用者資料在 Lua 中尋找 C 物件。

舉一個典型的例子,假設我們正在實作 Lua 和視窗系統之間的繫結。在此繫結中,我們使用完整使用者資料來表示視窗。(每個使用者資料可能包含整個視窗結構或僅包含系統建立的視窗指標。)當視窗內部發生事件(例如,滑鼠點擊)時,系統會呼叫特定的回呼,並透過其位址識別視窗。若要將回呼傳遞給 Lua,我們必須找到表示給定視窗的使用者資料。若要尋找此使用者資料,我們可以保留一個表格,其中索引是具有視窗位址的輕量級使用者資料,而值是表示 Lua 中視窗的完整使用者資料。一旦我們取得視窗位址,我們會將其作為輕量級使用者資料推入 API 堆疊,並使用使用者資料作為該表格的索引。(請注意,表格應具有弱值。否則,那些完整使用者資料將永遠不會被收集。)