Lua 元表metatable学习(制作常量表)

元表

元表其实就是一个表,用于增加和改变表的操作。

setmetatable(t, m): 将表t的元表设置为表m
getmetatable(t): 返回表t的元表

元方法

元表作为一个表,可以拥有任意类型的键值对,其真正对被设置的表的影响是Lua规定的元方法键值对。

这些键值对就是Lua所规定的键,比如__index,__add,__concat等等。这些键名都是以双斜杠__为前缀。其对应的值则为一个函数,被称为元方法(metamethod)。

在这里插入图片描述

示例

在这里插入图片描述
下面还演示了__call和__tostring

function V2(x,y)
	return setmetatable({
		x = x or 0,
		y = y or 0,
	},V2meta)
end

V2meta={
	-- 相加
	__add=function(a,b)
		return V2(a.x+b.x,a.y+b.y)
	end,
	
	-- 相减
	__sub=function(a,b)
		return V2(a.x-b.x,a.y-b.y)
	end,
	
	-- 调用自身 tb()
	__call=function(self)
		print(string.format("{%d, %d}",self.x,self.y))
	end,
	
	-- tostring
	__tostring=function(self)
		return string.format("{%d, %d}",self.x,self.y)
	end,
}

a = V2(1,2)
b = V2(2,3)
c = a+b
-- c()
print(c)

__index

如果当前查询的键没有值,那么Lua就会寻找该table的metatable中的__index 键,由__index进行处理

local meta={
	-- 为表添加默认key
	__index={
		sex='male',
		age=12,
	},
	-- function实现
	__index=function(self,index)
		if index=='sex' then
			return 'male'
		elseif index=='age' then
			return 12
		else
			return nil
		end
	end,
}

local tb=setmetatable({},meta)
-- __index中的值
print(tb['sex'])
-- 该键存在值后就不会再调用__index了
tb['sex']='female'
print(tb['sex'])

__newindex

__index是访问不存在字段,__newindex是对不存在字段赋值(非法操作的检测,例如防止lua代码写错)

local cg = {
	a=10
}

local meta={
	-- 对不存在字段修改时调用
	__newindex=function(this, key, value)
        print("尝试修改不存在字段:" .. key)
        rawset(this, key, value)
	end
	-- 为表时,会取代为:对这张表赋值
	__newindex=cg
}

tb = setmetatable({},meta)
tb.a=12
print(tb.a, cg.a)

根据__index和__newindex制作常量表

function const(tab)
	local meta={
		-- 按照tab的键值情况生成一个meta,所以下面setmetatable({},meta)中可以是{}
		-- 返回一个空table,起作用的是meta
		__index=function(self,key)
			if tab[key]==nil then
				error("尝试访问不存在的字段:" .. key)
			else
				return tab[key]
			end
		end,
		
		__newindex=function(self, key, value)
			error("尝试修改不存在字段:" .. key)
		end,
	}
	
	return setmetatable({},meta)
end

local tb = const({
	fire = true
})

print(tb.fire)
tb.fire=false

在这里插入图片描述

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 1024 设计师:白松林 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值