博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Lua 笔记--元表与元方法
阅读量:5740 次
发布时间:2019-06-18

本文共 2418 字,大约阅读时间需要 8 分钟。

        可以通过元表来修改一个值的行为,使其在面对一个非预定义的操作时执行一个指定的操作。当Lua试图将两个table相加时,它会先检查两者之一是否有元表,然后检查该原表中是否有一个叫__add的字段。

        Lua在创建新的table时不会创建元表,可以使用setmetatable来设置或修改任何table的元表。

        在Lua中,只能设置table的元表,若要设置其他类型的值的元表,则必须通过C代码来完成。其他类型在默认情况下都没有元表。

1、算术类的元方法

Set = {}local mt = {}--根据参数列表中的值创建一个新的集合function Set.new( l )	local set = {}	setmetatable(set, mt)		--将mt设置为当前所创建table的元表	for _, v in ipairs(l) do set[v] = true end	return set endfunction Set.union( a, b )	local res = Set.new{}	for k in pairs(a) do res[k] = true end 	for k in pairs(b) do res[k] = true end 	return resendfunction Set.intersection( a, b )	local res = Set.new{}	for k in pairs(a) do res[k] = b[k] end 	return res endfunction Set.tostring( set )	local l = {}	for e in pairs(set) do l[#l + 1] = e end 	return "{" ..table.concat(l, ", ") .. "}"			--table.concat函数会将给定列表中的所有字符串连接起来,并返回连接结果endfunction Set.print( s )	print(Set.tostring(s))ends1 = Set.new{1, 2, 3, 4}s2 = Set.new{2, 5}--两个集合具有一个相同的元表print(getmetatable(s1))		-->table: 0x7fee11c09940print(getmetatable(s2))		-->table: 0x7fee11c09940--将元方法加入元表中。mt.__add = Set.union --当Lua试图将两个集合相加时,就会调用Set.union函数,并将两个操作数作为参数传入s3 = s1 + s2Set.print(s3)		-->{1, 2, 3, 4, 5}--类似的,还可以使用乘号来求集合的交集mt.__mul = Set.intersection Set.print((s1 + s2) * s1)		-->{1, 2, 3, 4}--[[在元表中,每种算术操作符都有对应的字段名。除了__add 和__mul外,还有__sub(减法)、__div(除法)、__unm(相反数)、__mod(取模)、__pow(乘幂)。此外,还可以定义__concat字段,用于描述连接操作符的行为。]]

2、关系类的元方法

mt.__le = function ( a, b )		--集合包含	for k in pairs(a) do		if not b[k] then return false end 	end 	return trueendmt.__lt = function ( a, b )	return a <= b and not (b <= a)endmt.__eq = function ( a, b )	return a <= b and b <= a ends1 = Set.new{2, 4}s2 = Set.new{2, 4, 8}print(s1 <= s2)		-->trueprint(s1 < s2)		-->trueprint(s1 >= s2)		-->falseprint(s1 > s2)		-->falseprint(s1 == s2 * s1)		-->true

3、table访问的元方法

--[[当访问一个table中不存在的字段时,会促使解释器去查找一个叫__index的元方法。如果没有这个元方法,那么访问结果为nil,否则就由这个元方法来提供最终结果。]]Window = {}		--创建一个名字空间--使用默认值来创建一个原型Window.prototype = {x=0, y=0, width=100, height=200}Window.mt = {}		--创建元表 --声明构造函数function Window.new( o )	setmetatable(o, Window.mt)	return oend--定义__index元方法Window.mt.__index = function ( table, key )	return Window.prototype[key]end--__index不必是一个函数,还可以是一个table--Window.mt.__index = Window.prototype--创建一个新窗口,并查询一个它没有的字段w = Window.new{x = 10, y = 20}print(w.width)		-->100

        __newindex元方法与__index元方法类似,不同之处在于前者用于table的更新,而后者用于table的查询。当对一个table中不存在的索引赋值时,解释器就会查找__newindex元方法。如果有这个元方法,解释器就调用它,而不是执行赋值。

转载地址:http://jvbzx.baihongyu.com/

你可能感兴趣的文章
Linux的netstat命令使用
查看>>
lvm讲解,磁盘故障小案例
查看>>
大快网站:如何选择正确的hadoop版本
查看>>
经过这5大阶段,你离Java程序员就不远了!
查看>>
IntelliJ IDEA 连接数据库详细过程
查看>>
thymeleaf 学习笔记-基础篇
查看>>
PHP-X开发扩展
查看>>
android学习笔记——onSaveInstanceState的使用
查看>>
工作中如何做好技术积累
查看>>
怎么用sysLinux做U盘双PE+DOS??
查看>>
Spring Transactional
查看>>
shell脚本实例
查看>>
我的友情链接
查看>>
Windows Phone 7 隔离存储空间资源管理器
查看>>
Microsoft Excel 2000/2003修复工具
查看>>
apache安装报错undefined reference ssl
查看>>
关于爱情只有一句忠告
查看>>
CentOS 7下安装部署Oracle11g图文教程
查看>>
F#初学笔记06
查看>>
实战:将企业域名解析委派给企业DNS服务器
查看>>