lua metatable(元表)

时间:2022-06-01 19:41:02

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)