大部分代码参考《lua程序设计》。记录一下方便以后回头看~
算术类的元方法
如何用’+’,’*'来表示两个table的并集,交集等
Set={}
local mt={}
function Set.new(l)
local set={}
setmetatable(set,mt) -- 将mt设置为set的元表
for k,v in ipairs(l) do
set[v]=true -- val值作为key插入
end
return set
end
function Set.union(a,b)
local set=Set.new{}
for k in pairs(a) do set[k]=true end
for k in pairs(b) do set[k]=true end
return set
end
function Set.intersection(a,b)
local set=Set.new{}
for k in pairs(a) do set[k]=b[k] end
return set
end
-- 打印set集合的辅助函数
function Set.to_string(set)
local l={}
for i in pairs(set) do
l[#l+1]=i
end
return "{"..table.concat(l,",").."}"
end
function Set.print(set)
print(Set.to_string(set))
end
mt.__add=Set.union -- +代表并集
mt.__mul=Set.intersection -- *代表交集
s1=Set.new{10,20,30}
s2=Set.new{30,1}
Set.print(s1) -- {20,10,30}
Set.print(s2) -- {1,30}
s3=s1+s2
Set.print(s3) -- {20,1,10,30}
s4=s1*s2
Set.print(s4) -- {30}
s5=s1+{[8]=true,[9]=true} -- {8,9,10,20,30}
Set.print(s5)
关系类的元方法
用’<’, '<='判断子集关系
Set={}
local mt={}
function Set.new(l)
local set={}
setmetatable(set,mt) -- 将mt设置为set的元表
for k,v in ipairs(l) do
set[v]=true -- val值作为key插入
end
return set
end
function Set.union(a,b)
local set=Set.new{}
for k in pairs(a) do set[k]=true end
for k in pairs(b) do set[k]=true end
return set
end
function Set.intersection(a,b)
local set=Set.new{}
for k in pairs(a) do set[k]=b[k] end
return set
end
mt.__le=function (a,b) -- 判断a是不是b的子集 <=
for k in pairs(a) do
if not b[k] then return false end
end
return true
end
mt.__lt=function(a,b) -- <
return a<=b and not (b<=a)
end
mt.__eq=function(a,b) -- ==
return a<=b and b<=a
end
s1=Set.new{10,12}
s2=Set.new{12,43,10}
print(s1<s2) -- true
print(s1<=s2) -- true
print(s1==s2) -- false
库定义的元方法
Set={}
local mt={}
function Set.new(l)
local set={}
setmetatable(set,mt) -- 将mt设置为set的元表
for k,v in ipairs(l) do
set[v]=true -- val值作为key插入
end
return set
end
-- 打印set集合的辅助函数
function Set.to_string(set)
local l={}
for i in pairs(set) do
l[#l+1]=i
end
return "{"..table.concat(l,",").."}"
end
function Set.print(set)
print(Set.to_string(set))
end
s1=Set.new{10,20,30}
Set.print(s1) -- {20,10,30}
print(s1) -- table: 0x55996b735de0
mt.__tostring=Set.to_string
-- 函数print总是调用tostring来格式化输出。当格式化任意值时,tostring会检查该值
-- 是否有一个__tostring的元方法,tostring就用该值作为参数来调用这个元方法
print(s1) -- {20,10,30}
-- 让元表受到保护
mt.__metatable="not your business"
print(getmetatable(s1)) -- "not your business"
setmetatable(s1,{}) -- 不能修改, cannot change a protected metatable
table访问的元方法__index
-- 当访问一个table中不存在的字段时,得到的结果是nil,可以设置__index元方法得到其他结果
--
local information =
{
name = "tom",
age = 18,
sex = "man",
}
-- 打印一下信息
print("the information is :")
print(information.name)
print(information.age)
print(information.sex)
print(information.address) -- nil
local mt = {
__index = function(table, key)
print("I haven't this field : " .. key)
-- return table
end
}
function information.new(info)
-- 设置原表
setmetatable(info, mt)
return info
end
info=information.new{name="john",age=20}
-- 再次打印信息
print("\nafter set __index, the information is :")
print(info.name)
print(info.age)
print(info.sex)
print(info.address)
--[[
after set __index, the information is :
john
20
I haven't this field : sex
nil
I haven't this field : address
nil
--]]
设置默认值为0的写法:setDefault
-- 当访问一个table中不存在的字段时,得到的结果是nil,可以设置__index元方法得到其他结果
--
local information =
{
name = "tom",
age = 18,
sex = "man",
}
-- 打印一下信息
print("the information is :")
print(information.name)
print(information.age)
print(information.sex)
print(information.address) -- nil
local mt = {
__index = function(table, key)
print("I haven't this field : " .. key)
end
}
function setDefault(info,d)
-- 设置原表
-- defalut value=0
local mt = {
__index = function()
return d
end
}
setmetatable(info, mt)
end
info={name="john",age=20}
-- 再次打印信息
print("\nafter set __index, the information is :")
print(info.name)
print(info.age)
setDefault(info,0)
print(info.sex)
print(info.address)
--after set __index, the information is :
--john
--20
--0
--0