Set = {} Set.mt = {} function Set.new (t) local set = {} setmetatable(set, Set.mt) for _, l in ipairs(t) do set[l] = true -- print("set",_,l); end --第一个返回值 索引 作为 _ 被忽略使用 -- 使用 l 值 作为 新set表的 下表索引 设置为true 说明存在这个值 return set end function Set.union (a,b) --两个表相加 local res = Set.new{} for k,vv in pairs(a) do -- print("a",k,vv) res[k] = true end --遍历表 for k in pairs(b) do res[k] = true -- print("b",k) end return res end function Set.intersection (a,b) 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.print(Set) s1 = Set.new{10, 20, 30, 50} s2 = Set.new{30, 1} print(getmetatable(s1)) --> table: 00672B60 print(getmetatable(s2)) --> table: 00672B60 print("--给metatable增加__add函数。") Set.mt.__add = Set.union s3 = s1 + s2 Set.print(s3) --> {1, 10, 20, 30, 50} print("----同样的我们可以使用相乘运算符来定义集合的交集操作") Set.mt.__mul = Set.intersection Set.print((s1 + s2)*s1) --> {10, 20, 30, 50} --Metatables也允许我们使用metamethods: --__eq(等于),__lt(小于),和__le(小于等于)给关系运算符赋予特殊的含义。 Set.mt.__le = function (a,b) -- set containment --<= for k in pairs(a) do -- print(k) if not b[k] then return false end end return true end Set.mt.__lt = function (a,b) --< return a <= b and not (b <= a) end --最后,我们通过集合的包含来定义集合相等 Set.mt.__eq = function (a,b) --= return a <= b and b <= a end --有了上面的定义之后,现在我们就可以来比较集合了: print("--比较集合") s1 = Set.new{2, 4,2,2,2,2} s2 = Set.new{4, 10, 2} print(s1 <= s2) --> true print(s1 < s2) --> true print(s1 >= s1) --> true print(s1 > s1) --> false print(s1 == s2 * s1) --> true --设置 metatables的 __tostring域 Set.mt.__tostring = Set.tostring print("--tostring"); s1 = Set.new{10, 4, 5} print(s1) --> {4, 5, 10} print("--保护metatables") Set.mt.__metatable = "not your business" s1 = Set.new{} print(getmetatable(s1)) --> not your business --下面设置metatable将直接编译报错 --setmetatable(s1, {}) --stdin:1: cannot change protected metatable