lua中的元表和元方法
来源:互联网 发布:手机推荐 知乎 编辑:程序博客网 时间:2024/04/27 21:21
元表概念
Lua中,面向对象是用元表这种机制来实现的
元表(matatable)
Lua在创建新的table时不会创建元表,比如以下代码就可以演示:
local t = {1, 2}print(getmetatable(t)) -- nil
设置元表和获取元表(getmetatable和setmetatable)
使用getmetatable来获取一个table或userdata类型变量的元表,当创建新的table变量时,使用getmetatable去获得元表,将返回nil;同理,我们也可以使用setmetatable去设置一个table或userdata类型变量的元表
local t = {}print(getmetatable(t)) -->nil 创建新的table,还没有设置元表,故为nillocal t1 = {}setmetatable(t, t1) --设置元表assert(getmetatable(t) == t1)
任何table都可以作为任何值得元表,而一组相关的table有可以共享一个通用的元表,此元表描述了它们共同的行为。一个table甚至可以作为它自己的元表,用于描述其特有的行为。总之,任何搭配形式都是合法的
Set = {}local mt = {} -- 集合的元表-- 根据参数列表中的值创建一个新的集合function Set.new(l) local set = {} setmetatable(set, mt) --每调用一次这个函数,就创建一个set,并设置元表mt for _, v in pairs(l) do set[v] = true end return setend-- 并集操作function Set.union(a, b) local retSet = Set.new{} -- 此处相当于Set.new({}) for v in pairs(a) do retSet[v] = true end for v in pairs(b) do retSet[v] = true end return retSetend
所有由Set.new创建的集合都具有一个相同的元表,例如
local set1 = Set.new({10, 20, 30})local set2 = Set.new({1, 2})print(getmetatable(set1))print(getmetatable(set2))assert(getmetatable(set1) == getmetatable(set2)) --他们的元表都是一样的
最后,我们需要把元方法加入元表中,代码如下:
mt.__add = Set.union
local set1 = Set.new({10, 20, 30})local set2 = Set.new({1, 2})local set3 = set1 + set2Set.print(set3)
保护元表
保护元表,用字段__metatable。当我们想要保护集合的元表,是用户既不能看也不能修改集合的元表,那么就需要使用__metatable字段了;当设置了该字段时,getmetatable就会返回这个字段的值,而setmetatable则会引发一个错误;如以下演示代码:
function Set.new(l) local set = {} setmetatable(set, mt) for _, v in pairs(l) do set[v] = true end mt.__metatable = "You cannot get the metatable" -- 设置完我的元表以后,不让其他人再设置 return setendlocal tb = Set.new({1, 2})print(tb)print(getmetatable(tb)) --得到You cannot get the metatablesetmetatable(tb, {}) -- 这儿已经不能设置元表的了
__index元方法:
默认情况下,当我们访问一个table中不存在的字段时,得到的结果是nil。但是这种状况很容易被改变;Lua是按照以下的步骤决定是返回nil还是其它值得:
当访问一个table的字段时,如果table有这个字段,则直接返回对应的值;
当table没有这个字段,则会促使解释器去查找一个叫__index的元方法,接下来就就会调用对应的元方法,返回元方法返回的值;
如果没有这个元方法,那么就返回nil结果。
Student = {} -- 创建一个命名空间-- 创建默认值表Student.default = { name= "zhangsan", age = 18, id = 1101 }Student.mt = {} -- 创建元表-- 声明构造函数function Student.new(o) setmetatable(o, Student.mt) --设置元表 return oend-- 定义__index元方法Student.mt.__index = function (table, key) return student.default[key]endlocal s = Student.new(name = "lisi")print(s.name) -- >lisi 访问自身已经拥有的值print(s.age) -- >18 访问default表中的值print(s.id) -- >1101 访问default表中的值
- Lua 中的元表和元方法
- Lua中的元表和元方法
- Lua中的元表和元方法
- Lua中的元表和元方法
- Lua中的元表和元方法
- Lua中的元表和元方法
- Lua中的元表和元方法
- Lua中的元表和元方法
- Lua中的元表和元方法
- lua中的元表和元方法
- lua中的元表和元方法解析
- Lua中的元表与元方法
- Lua中的元表与元方法
- Lua中的元表与元方法
- Lua中的元表与元方法
- Lua中的元表与元方法
- Lua元表和元方法
- Lua 元表和元方法
- Android混合架构的实践
- 概率统计基础-置信区间
- WebRtc中的AEC算法
- JZOJ 4669 弄提纲
- 自己写一个hibernate的小demo
- lua中的元表和元方法
- core libvlc error: No plugins found! Check your VLC installation.
- SET XACT_ABORT ON
- 数据结构-查找
- 清除css浮动的方法
- Ubuntu16.04安装mongodb
- 优化版弹性ScrollView
- 区间DPの矩阵取数游戏
- 多线程day1.demo2