Lua 基礎之元表

2021-08-03 21:08:24 字數 4957 閱讀 4890

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...