Set = {}
function Set.new (t) --所有通过new的表都有相同的元表了
local set = {}
setmetatable(set, Set.mt)
for _, l in ipairs(t) do --这里取出来的表是无序的
set[l] = true
end
return set
end
function Set.union (a,b) --这里把2个集合组合成一个集合 相同key值得做覆盖操作b覆盖a
if getmetatable(a) ~= Set.mt or getmetatable(b) ~= Set.mt then --b不是table 所以b的元表不等于Set.mt
error("尝试 add 但是参数不能是一个value 只能是table", 2)
end
local res = Set.new{}
for k in pairs(a) do
res[k] = true
end
for k in pairs(b) do
res[k] = false --书上这里是true我改成了false 结果res 集合变成了1 30 10 50 20
end
return res
end
function Set.intersection (a,b) --这个是返回2个集合的交集
local res = Set.new{}
for k in pairs(a) do
res[k] = b[k]
end
return res
end
function Set.tostring (set)
local s = "{"
local sep = ""
for e in pairs(set) do
s = s .. sep .. e
sep = ", "
end
return s .. "}"
end
function Set.print (s)
print(Set.tostring(s))
end
Set.mt = {} -- Set的元表
s1 = Set.new{10, 20, 30, 50}
s2 = Set.new{30, 1}
print(getmetatable(s1)) --> table: 0060D078
print(getmetatable(s2)) --> table: 0060D078
Set.print(s1)
Set.mt.__add = Set.union --通过元表 2个表相加 给元表设置元方法 该元方法的操作就是把2个集合合并 相同key值得做覆盖操作
s3 = s1 + s2
Set.print(s3) --> {1, 30, 10, 50, 20}
Set.mt.__mul = Set.intersection --通过元表 2个表相减 给元表设置元方法 该元方法的操作就是把2个集合中有交集的部分给res 然后返回res
Set.print((s1 + s2)*s1) --> {10, 20, 30, 50} --这里s1+s2后值直接赋值给了intersection的第一个参数
s = Set.new{1,2,3}
s = s + 8 --加法不能是值 这里因为s是有add元方法的 lua只判断第一个 如果第2个值不符合要求 就只能在函数里面自行判断了