lua metatable (元表)
概述
普通 table 类型的表仅能够做一些单表操作, 无法进行一些特殊的以及两个表的操作, 比如 table1 + table2, print(table3)
lua 的元表可以理解为一个存储操作方法的 table, 将表指定某个元表, 其实就是将一些操作绑定到了原表上
语法定义
setmetatable(table, metatable)
getmetatable(table)
示例程序
mytable1 = {name = "liao", age = 18} mymetatable1 = {sex = "male"} setmetatable(mytable1, mymetatable1) mytable2 = setmetatable({}, {}) metat = getmetatable(mytable1) for k, v in pairs(mytable1) do print(k, v) end
常用元方法
元方法有点类似于 php 的魔术方法的意思
__index
示例程序
mytable = setmetatable({k1 = "v1"}, { __index = function(mytable, k) if k == "k2" then return "v2" else return nil end end }) print(mytable.k1, mytable.k2, mytable.k3)
__newindex
示例程序
mymetatable = {} mytable = setmetatable({k1 = "v1"}, { __newindex = mymetatable }) mytable.k1 = "hello" mytable.k2 = "world" print(mytable.k1, mytable.k2, mymetatable.k1, mymetatable.k2) // 若要将赋值赋给原表, 需要使用 rawset 函数 mymetatable2 = {} mytable2 = {k1 = "v1"} mymetatable2.__newindex = function(mytable2, k, v) rawset(mytable2, k, v) end
__add
示例程序
local mytable1 = {1, 2, 3} local mytable2 = {4, 5, 6} local mymetatable = {} // 将 t2 的数据加入 t1 mymetatable._add = function(t1, t2) for i = 1, #t2 do table.insert(t1, #t1 + 1, t2[i]) end return t1 end setmetatable(mytable1, mymetatable) local mytable3 = mytable1 + mytable2 for k, v in pairs(mytable3) do print(k, v) end
__sub
示例程序
local mytable1 = {1, 2, 3, 4, 5, 6} local mytable2 = {2, 3} local mymetatable = {} function removeFromTable(t, val) for k, v in pairs(t) do if v == val then table.remove(t, k) end end return t end mymetatable.__sub = function(t1, t2) for i = 1, #t2 do t1 = removeFromTable(t1, t2[i]) end return t1 end setmetatable(mytable1, mymetatable) local mytable3 = mytable1 - mytable2 for k, v in pairs(mytable3) do print(k, v) end
__mul
示例程序
local mytable1, mytable2, mymetatable = {1, 2, 3}, {4, 5}, {} mymetatable.__mul = function(t1, t2) for i = 1, #t1 do local m1, m2 = t1[i], t2[i] if not m2 then m2 = 1 end t1[i] = m1 * m2 end return t1 end setmetatable(mytable1, mymetatable) local mytable3 = mytable1 * mytable2 for k, v in pairs(mytable3) do print(k, v) end
__div
示例程序
local t1, t2, meta = {10, 9, 8}, {5, 4}, {} meta.__div = function(t1, t2) for i = 1, #t1 do local d1, d2 = t1[i], t2[i] if not d2 then d2 = 1 end t1[i] = d1 / d2 end return t1 end setmetatable(t1, meta) local t3 = t1 / t2 for k, v in pairs(t3) do print(k, v) end
__mod
示例程序
local t1, t2, meta = {10, 9, 8}, {5, 4}, {} meta.__mod = function(t1, t2) for i = 1, #t1 do if not t2[i] or t2[i] == 0 then break end t1[i] = t1[i] % t2[i] end return t1 end setmetatable(t1, meta) local t3 = t1 % t2 for k, v in pairs(t3) do print(k, v) end
__unm
示例程序
local t1, meta = {1, 2, 3}, {} meta.__unm = function(t1) for i = 1, #t1 do t1[i] = -t1[i] end return t1 end setmetatable(t1, meta) local t3 = -t1 for k, v in pairs(t3) do print(k, v) end
__concat
示例程序
local t1, t2, meta = {1, 2, 3}, {4, 5, 6}, {} meta.__concat = function(t1, t2) for i = 1, #t1 do t1[i] = t1[i] .. t2[i] end return t1 end setmetatable(t1, meta) local t3 = t1 .. t2 for k, v in pairs(t3) do print(k, v) end
__eq
示例程序
local t1, t2, meta = {1, 2, 3}, {1, 2, 3}, {} meta.__eq = function(t1, t2) for i = 1, #t1 do if t1[i] ~= t2[i] then return false end end return true end setmetatable(t1, meta) local compare = t1 == t2 print(compare)
__lt
示例程序
local t1, t2, meta = {1, 2, 3}, {4}, {} meta.__lt = function(t1, t2) local sum1, sum2 = 0, 0 for i = 1, #t1 do sum1 = sum1 + t1[i] end for i = 1, #t2 do sum2 = sum2 + t2[i] end if sum1 < sum2 then return true else return false end end setmetatable(t1, meta) local compare = t1 < t2 print(compare)
__le
示例程序
local t1, t2, meta = {1, 2, 3}, {1, 2, 3}, {} meta.__le = function(t1, t2) local sum1, sum2 = 0, 0 for i = 1, #t1 do sum1 = sum1 + t1[i] end for i = 1, #t2 do sum2 = sum2 + t2[i] end if sum1 <= sum2 then return true else return false end end setmetatable(t1, meta) local compare = t1 <= t2 print(compare)
__call
示例程序
local t1, t2, meta = {1}, {2, 3}, {} meta.__call = function(t1, t2) local sum = 0 for i = 1, #t1 do sum = sum + t1[i] end for i = 1, #t2 do sum = sum + t2[i] end return sum end setmetatable(t1, meta) local sum = t1(t2) print(sum)
__tostring
示例程序
local t1, meta = {1, 2, 3}, {} meta.__tostring = function(t) local str = '' for i = 1, #t do str = str .. t[i] .. "###" end return str end setmetatable(t1, meta) print(t1)