Lua学习(六)元表和元方法

阅读更多
  可以通过一个元表修改一个值的行为,使其在面对一个非预定义操作时执行一个指定操作
元表:metatable

元方法:metemethod
__add        --加法
__mul        --乘法
__sub        --减法
__div        --除法
__unm        --相反数
__mod        --取模
__pow        --乘幂
__concat     --字符串连接

__eq         --相等
__lt         --小于
__le         --小于等于

__index      --如果读取table中不存在的索引的值时,执行该元方法
__newindex   --如果对table不存在的索引赋值,执行该元方法



示例一:算术类的元方法
--创建元表:
local tuple_mt = {}

--元方法:生成新表
function tuple_mt.new(t)
    setmetatable(t, tuple_mt)     --将mt设为t的元表
    return t
end

--元方法:将t1和t2执行对应操作
function tuple_mt.__add(t1, t2)
    ret = {}
    ret.addends = t1.addends + t2.addends
    ret.multi = t1.multi * t2.multi
    return ret
end

--测试用例:
ta = tuple_mt.new{addends=2, multi = 2}
tb = tuple_mt.new{addends=3, multi = 3}
tc = ta + tb
for i,v in pairs(tc) do
    print(i,v)        
end
---最后输出结果
addends 5
multi   6


示例二:__index元方法:当试图访问table中不存在的索引时,如果找到__index元方法,那么执行这个元方法,找不到就返回nil值
local mt = {}
local key = {}        --将一个table设为唯一的key
function mt.__index(t)
    return t[key]
end

function setDefaul(t, DefaultVal) 
    t[key] = DefaultVal      --将默认值保存到原数组中,这样,不同默认值的table可以共用一个元表mt
    setmetatable(t, mt)
end

tab = {"Mday", "Tday", "Wday"}
setDefault(tab, "Noday")
print(tab[1],tab[8])        --输出结果:Mday,Noday
    


示例三:__newindex元方法:试图给table不能存在索引赋值是,查找__newindex方法,如果有__newindex方法,就执行
local mt = {}
local index = {}             --创建私有索引

function mt.__index(t,k)
    print("visit element  " .. tostring(k))
    return t[index][k]
end

function mt.__newindex(t,k,v)
   print("set element  " .. tostring(k).." to "..tostring(v))
   t[index][key] = v
end

function trace(t)   
    local proxy = {}
    proxy[index] = t
    setmetatable(proxy, mt)
    return proxy
end

tab = trace({})
tab[2] = "hello world"
print(tab[2])
   


示例四:只读表
function setReadOnly(t)
    local mt = {}
    local proxy = {}

    mt.__index = t

    function mt.__newindex(t,k,v)
       error("deny to modify", 2)
    end

   setmetatable(proxy, mt) 
   return proxy
end

days = setReadyOnly{"Mday", "Tday", Wday"}
print(days[1]
days[9] = "NiceDay"

你可能感兴趣的:(Lua学习(六)元表和元方法)