• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Lua中的元表Metatable ——table相关的使用

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

接上篇:

2、__newindex Metamethod

__index metamethod是对table的访问,__newindex metamethod则是用来对表的更新。当给表的一个缺少的域赋值时,lua解释器会查找__newindex metamethod,如果存在,则调用这个函数而不进行赋值操作。

详细的,在lua面向对象编程中介绍。

 

3、下边介绍几种利用metatable 实现的功能和表的操作。

有默认值的表,当我们访问一个表不存在的域的时候,默认值是nil,我们可以通过metatable改变它的默认值。

第一种方式:这样改变多个表的默认值代价太大。

-------------代码段-----------------
local Set = {}
function Set.SetDefaultValue(tab, value)
	setmetatable(tab, {__index = function() return value end})
end
-- 测试
local test_table = {}
Set.SetDefaultValue(test_table, "*")
print(test_table.x)		-->*
-------------代码段-----------------

第二种方式:把默认值放在自己的表中的一个域。

-------------代码段-----------------
local Set = {}
local meta_table = {__index = function(tab) return tab.___default___value end}
function Set.SetDefaultValue(tab, value)
	tab.___default___value = value
	setmetatable(tab, meta_table)
end
-- 测试
local test_table = {}
Set.SetDefaultValue(test_table, "*")
print(test_table.x)		-->* 这种方式用ipairs可以遍历到
-------------代码段-----------------

第三种方式:新建一个表作为键值,可以保证这个键值的唯一性。

-------------代码段-----------------
local Set={}
function Set.SetDefaultValue(tab, value)
	local key={}	
	local meta_table = {__index = 
		function(tab) 
			return tab[key]
		end}
	tab[key] = value
	setmetatable(tab, meta_table)
end
-- 测试
local test_table = {}
Set.SetDefaultValue(test_table, "*")
print(test_table.x)		-->* 这种方式用ipairs可以遍历到
-------------代码段-----------------

监控对一个表的操作,使用代理table。

-------------代码段-----------------
local index = {}	--为了保证域的唯一性
local mt = {
	__index = function(t,k)
		print("access table element: " .. tostring(k))
		return t[index][k]
	end,
	__newindex = function(t,k,v)
		print("change table valu: " ..
			tostring(k) .. " = " ..tostring(v))
		t[index][k] = v
	end
}
-- 设置代理表
function track(t)
	local proxy = {}
	proxy[index] = t
	setmetatable(proxy,mt)
	return proxy
end
-- 测试
local mytable = {}
mytable = track(mytable)
mytable["sex"] = "man"
print(mytable["sex"])
-------------代码段-----------------

 

 

实现只读表:

-------------代码段-----------------
--[[
	这里注意函数error(param1,param2)
	param1=>错误信息
	param2=>可选参数,默认为1打印会显示调用error的位置(文件+行号),
							2 显示调用的函数
							0 不显示错误位置信息
]]--
function create_only_reader_table(tab)
	local proxy = {}
	local mt = {
		__index = tab,
		__newindex = function(t,k,v)
			error("not change table value", 2)
		end
	}
	setmetatable(proxy, mt)
	return proxy
end
-- 测试
local info = {["name"] = "xiaoming", ["sex"] = "man", ["prof"] = "teacher"}
local tab = create_only_reader_table(info)
tab["name"] = "ww"
-------------代码段-----------------

 

Metatable总结:

1、算术域、关系域、库的域、表的域、(域这里指__add、__le、__index等),通过设置这些域的值(值可以是函数、表、字符串、变量等),来改变lua原有的行为。

2、通过设置多个相同表的共同原表,可以模拟面向对象中的继承。

3、通过设置自己的原表,描述自己私有行为。

-------------2018/10/19-----------

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
秒杀代码,非lua脚本。发布时间:2022-07-22
下一篇:
Lua(十五)——协同程序发布时间:2022-07-22
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap