- Lua 教程
- Lua - 首頁
- Lua 基礎
- Lua - 概述
- Lua - 環境
- Lua - 基本語法
- Lua - 註釋
- Lua - 列印 Hello World
- Lua - 變數
- Lua - 資料型別
- Lua - 運算子
- Lua - 迴圈
- Lua - 決策制定
- Lua - 函式
- Lua - 日期和時間
- Lua 陣列
- Lua - 陣列
- Lua - 多維陣列
- Lua - 陣列長度
- Lua - 遍歷陣列
- Lua 迭代器
- Lua - 迭代器
- Lua 列表
- Lua - 在列表中搜索
- Lua 模組
- Lua - 模組
- Lua - 名稱空間
- Lua 元表
- Lua - 元表
- Lua 協程
- Lua - 協程
- Lua 檔案處理
- Lua - 檔案 I/O
- Lua 庫
- Lua - 標準庫
- Lua - 數學庫
- Lua - 作業系統功能
- Lua 有用資源
- Lua - 快速指南
- Lua - 有用資源
- Lua - 討論
Lua - 元表
元表是一個表,它透過一組鍵和相關的元方法來幫助修改與其關聯的表的行為。這些元方法是強大的 Lua 功能,可以實現以下功能:
更改/新增表格上運算子的功能。
當鍵在表中不可用時,使用元表中的 __index 來查詢元表。
在處理元表時,有兩種重要的方法:
setmetatable(table,metatable) - 此方法用於為表設定元表。
getmetatable(table) - 此方法用於獲取表的元表。
讓我們首先了解如何將一個表設定為另一個表的元表。如下所示。
mytable = {}
mymetatable = {}
setmetatable(mytable,mymetatable)
以上程式碼可以表示為一行,如下所示。
mytable = setmetatable({},{})
示例 - _index
下面是一個簡單的元表示例,用於在表中找不到時查詢元表。
main.lua
mytable = setmetatable({key1 = "value1"}, {
__index = function(mytable, key)
if key == "key2" then
return "metatablevalue"
else
return nil
end
end
})
print(mytable.key1, mytable.key2)
輸出
執行以上程式時,將獲得以下輸出。
value1 metatablevalue
讓我們分步解釋以上示例中發生的情況。
這裡的 mytable 表是 {key1 = "value1"}。
為 mytable 設定了元表,其中包含 __index 的函式,我們將其稱為元方法。
元方法的工作很簡單,查詢索引 "key2",如果找到,則返回 "metatablevalue",否則返回 mytable 對應索引的值。
我們可以將以上程式簡化為如下所示。
mytable = setmetatable({key1 = "value1"},
{ __index = { key2 = "metatablevalue" } })
print(mytable.key1,mytable.key2)
示例 - __newindex
當我們在元表中新增 __newindex 時,如果表中不存在鍵,則新鍵的行為將由元方法定義。下面是一個簡單的示例,在主表中不存在索引時設定元表的索引。
main.lua
mymetatable = {}
mytable = setmetatable({key1 = "value1"}, { __newindex = mymetatable })
print(mytable.key1)
mytable.newkey = "new value 2"
print(mytable.newkey,mymetatable.newkey)
mytable.key1 = "new value 1"
print(mytable.key1,mymetatable.newkey1)
輸出
執行以上程式時,將獲得以下輸出。
value1 nil new value 2 new value 1 nil
您可以在以上程式中看到,如果鍵存在於主表中,則它只更新它。當鍵在 maintable 中不可用時,它會將該鍵新增到元表中。
示例 - 更新表
另一個使用 rawset 函式更新同一表的示例如下所示。
main.lua
mytable = setmetatable({key1 = "value1"}, {
__newindex = function(mytable, key, value)
rawset(mytable, key, "\""..value.."\"")
end
})
mytable.key1 = "new value"
mytable.key2 = 4
print(mytable.key1,mytable.key2)
輸出
執行以上程式時,將獲得以下輸出。
new value "4"
rawset 在不使用元表的 __newindex 的情況下設定值。類似地,rawget 在不使用 __index 的情況下獲取值。
示例 - 向表新增運算子行為
下面是一個簡單的示例,使用 + 運算子組合兩個表:
main.lua
mytable = setmetatable({ 1, 2, 3 }, {
__add = function(mytable, newtable)
for i = 1, table.maxn(newtable) do
table.insert(mytable, table.maxn(mytable)+1,newtable[i])
end
return mytable
end
})
secondtable = {4,5,6}
mytable = mytable + secondtable
for k,v in ipairs(mytable) do
print(k,v)
end
輸出
執行以上程式時,將獲得以下輸出。
1 1 2 2 3 3 4 4 5 5 6 6
元表中包含 __add 鍵,以新增 + 運算子的行為。鍵和對應運算子的表如下所示。
| 序號 | 模式和描述 |
|---|---|
| 1 | __add 更改 + 運算子的行為。 |
| 2 | __sub 更改 - 運算子的行為。 |
| 3 | __mul 更改 * 運算子的行為。 |
| 4 | __div 更改 / 運算子的行為。 |
| 5 | __mod 更改 % 運算子的行為。 |
| 6 | __unm 更改 - 運算子的行為。 |
| 7 | __concat 更改 .. 運算子的行為。 |
| 8 | __eq 更改 == 運算子的行為。 |
| 9 | __lt 更改 < 運算子的行為。 |
| 10 | __le 更改 <= 運算子的行為。 |
示例 - __call
使用 __call 語句新增方法呼叫的行為。一個簡單的示例,返回主表中值與傳遞表的總和。
main.lua
mytable = setmetatable({10}, {
__call = function(mytable, newtable)
sum = 0
for i = 1, table.maxn(mytable) do
sum = sum + mytable[i]
end
for i = 1, table.maxn(newtable) do
sum = sum + newtable[i]
end
return sum
end
})
newtable = {10,20,30}
print(mytable(newtable))
輸出
執行以上程式時,將獲得以下輸出。
70
示例 - __tostring
要更改 print 語句的行為,我們可以使用 __tostring 元方法。下面是一個簡單的示例。
main.lua
mytable = setmetatable({ 10, 20, 30 }, {
__tostring = function(mytable)
sum = 0
for k, v in pairs(mytable) do
sum = sum + v
end
return "The sum of values in the table is " .. sum
end
})
print(mytable)
輸出
執行以上程式時,將獲得以下輸出。
The sum of values in the table is 60
如果您完全瞭解元表的功能,那麼您可以執行許多操作,而無需使用它,這些操作將非常複雜。因此,嘗試更多地使用元表以及元表中提供的不同選項,如示例中所解釋的那樣,並建立您自己的示例。