Lua入门(一)元表与元方法

大部分代码参考《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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值