print(getmetatable("hello")) -- 003e7050
print(getmetatable("lua")) -- 003e7050
print(getmetatable(12)) -- nil
print(getmetatable({})) -- nil
t = {}
print(getmetatable(t)) -- nil
setmetatable(t, {})
print(getmetatable(t)) --0048a700
-- 定義元表
local mt = {}
set = {}
set.new = function(l)
local
set = {}
-- 設定元表
setmetatable(set, mt)
for _, v in ipairs(l) do
set[v] = true
end return
setend
set.union = function(a, b)
local res = {}
for k in pairs(a) do
res[k] = true
end for k in pairs(b) do
res[k] = true
end return res
endset.intersection = function(a, b)
local res = {}
for k in pairs(a) do
if b[k] then
res[k] = true
end end
return res
endset.tostring = function(a)
local l = {}
for k in pairs(a) do
l[#l + 1] = k
end return
""end
set.print = function(a)
print(set.tostring(a))
end-- 給元表新增元方法
mt.__add = set.union
mt.__mul = set.intersection
set1 = set.new()
set2 = set.new()
print(getmetatable(set1) == getmetatable(set2))
-- set3 = set.union(set1, set2)
set3 = set1 + set2
set.print(set3)
set3 = set1 * set2
set.print(set3)
mt.__le = function(a, b)
for k, v in pairs(a) do
ifnot b[k] then
return
false
end end
return
true
endmt.__lt = function(a, b)
return
a<= b and
not (b <= a)
endmt.__eq = function(a, b)
return
a<= b and b <= a
endset1 = set.new()
set2 = set.new()
print(set1 < set2) -- true
print(set1 > set2) -- false
print(set1 <= set2) -- true
print(set1 == set2) -- false
print(set1 == set.new()) -- true
print(set1 == ) -- false
-- print(1 < "hello") -- error
mt.__tostring = set.tostring
-- 下面兩條語句等價
print(set1)
print(set.tostring(set1))
-- 保護元表
mt.__metatable = "不能訪問"
s = set.new({})
print(getmetatable(s))
-- setmetatable(s, {}) -- error
window = {}
-- 定義原型
window.propotype =
-- 定義元表
window.mt = {}
-- __index 的值可以是函式
window.mt.__index = function
(t, k)
return window.propotype[k]
end-- __index 的值也可以是 table
-- window.mt.__index = window.propotype
-- 建構函式
window.new = function
(o) setmetatable(o, window.mt)
return o
endwin = window.new()
print(win.x, win.width) -- 0 100
print(win.x, rawget(win, width)) -- 0 nil
window.mt.__newindex = function
(t, k, v)
window.propotype[k] = v
endwin["color"] = "red"
print(win.color, rawget(win, "color")) -- red nil
rawset(win, "weight", 8)
print(win.weight, rawget(win, "weight")) -- 8 8
使用這種方式很簡單,只需要讓 __index 元方法固定返回乙個值即可;但這種方式必須為每個 table 新建立乙個元表,開銷比較大
setdefault = function
(t, value)
local mt =
setmetatable(t, mt)
endlocal t = {}
print(t.x) -- nil
setdefault(t, 10)
print(t["x"]) -- 10
由於預設值是與元方法 __index 關聯在一起的,因此無法直接在元方法中儲存和返回多個預設值;可以將預設值儲存在各個 table 本身,然後使用乙個 key 在元方法中訪問
- 如果不考慮名字衝突的話,可使用 _ 來表示這個 key
-- 共同的元表
local mt =
setdefault = function
(t, value)
-- 預設值儲存在 table 本身
t.___ = value
setmetatable(t, mt)
end
local key = {}
mt =
setdefault = function
(t, value)
-- 預設值儲存在 table 本身
t[key] = value
setmetatable(t, mt)
end
只有乙個 table 為空表時,才能保證每次訪問 table 的字段才能定位到 __index 或 __newindex;因此可以建立乙個空的 table 作為原 table 的**,然後在這個空的 table 的 __index 和 __newindex 中訪問原 table 的字段
setagent = function
(t) local agent = {}
local mt =
setmetatable(agent, mt)
return agent
endlocal t =
t = setagent(t)
print(t.x)
print(t.w)
t.w = 100
print(t.w)
通過函式 setagent 給表 t 設定了乙個**空表,然後把這個空表賦給 t,之後對錶 t 的操作都是通過這個空表來操作的,通過這個空表的 __index 和 __newindex 來操作原來的表
使用跟預設值一樣的方式,把原來的 table 儲存到各個**本身,然後元表通過 key 來訪問
local index = {}
local mt =
setagent = function
(t) local agent = {}
agent[index] = t
setmetatable(agent, mt)
return agent
end
通過**很容易實現唯讀的 table,只需要在設定值的時候返回乙個錯誤即可
readonly = function
(t) local mt =
local agent = {}
setmetatable(agent, mt)
return agent
endt = readonly(t)
t.x = 10
-- error
Lua基礎之元表(metatable)
lua中的元表允許我們通過乙個tablea特殊的鍵值自定義另乙個tableb的行為,這些特殊的鍵值稱為元方法,tablea則稱為tableb的元表。函式 描述 index 呼叫乙個索引 newindex 給乙個索引賦值 add 運算子 sub 運算子 mul 運算子 div 運算子 mod 運算子 ...
Lua學習之元表
在 lua table 中我們可以訪問對應的key來得到value值,但是卻無法對兩個 table 進行操作。因此 lua 提供了元表 metatable 允許我們改變table的行為,lua中的每個值都可以用乙個metatable來表示,每個行為則關聯了對應的元方法。元表的處理有兩個很重要的函式 ...
Lua元表和元表方法
今天學習lua中的元表,書上講的太難懂了,網上搜尋教程也將的模模糊糊,搜了一會總結了一下經驗,跟大家分享一下,希望對您有所幫助。如何設定元表?local t local mt getmetatable t nil setmetatable t,mt 將t1設定為t的元表 getmetatable t...