Metatable:

  lua中的每一个表都有其Metatable,默认情况下Metatable为nil。可通过setmetatable函数设置或者改变一个表的Metatable,

也可以通过getmetatable得到一个表的Metatable。任何一个表都可以是其它表的Metatable,可以多个表共享一个Metatable,

一个表也可以是自身的Metatable。

作用:使我们可以改变table的行为

  在metatable中设置__add, __sub, __mul, __div, __eq(等于), __lt(小于), __le(小于等于), __unm(负), __pow(幂),

__concat (定义连接行为),__tostring等metamethod方法,可以实现类似于C++中运算符重载的效果。

实例:

 Set = {}
Set.mt = {}
--setmetatable(Set.mt, Set.mt) function Set:new( t )
local tb = t or {}
setmetatable(tb, Set.mt)
return tb
end function Set.union( a, b )
local res = Set.new()
for _, k in pairs(a) do
table.insert(res, k)
end
for _, k in pairs(b) do
table.insert(res, k)
end
return res
end function Set.tostring( set )
local s = "{\n"
local sep = " "
for _, k in pairs(set) do
if type(k) == "boolean" then
k = "boolean"
elseif type(k) == "function" then
k = "function"
elseif type(k) == "table" then
-- k = "table"
k = Set.tostring(k)
end
s = s.." [".._.."]".." = "..k.."\n"
end
return s.."}"
end local s1 = Set:new({, , , })
local s2 = Set:new({, }) Set.mt.__add = Set.union
Set.mt.__concat = Set.union
Set.mt.__tostring = Set.tostring local s3 = s1 + s2
print(s3) local s4 = s1..s2
print(s4) 这里+和..是等价的,所以s3==s4,结果:
{
[] =
[] =
[] =
[] =
[] =
[] =
}
{
[] =
[] =
[] =
[] =
[] =
[] =
}

  当我们对两个有不同metatable的表进行加操作时,则检查第一个表的metatabled是否有__add,有则用之,
没有就再去检查第二个表。。。还没有就报错。

__index:

  我们在访问一个表不存在的域时,lua解释器会去查找metatabled中是否有__index方法(metamethod),如果不存在则返回nil,

否则由__index方法返回。__index可以是函数也可以是表

 Set.mt.__index = function (tb, key)--这里会传进来一个table和key
return "get "..key.." is null"
end -- Set.mt.__index = {sex = "man"} local myTb = Set:new({name = "Mical", age = })
print(myTb.name)
print(myTb.age)
print(myTb.sex) 结果:
Mical get sex is null

__newindex:

  当你给表不存在的值赋值时,lua解释器就会查找对应Metatable中的__newindex方法(metamethod)。如果存在则调用这个函数而不进行赋值。

 Set.mt.__newindex = function (tb, key, val)
print("can't set "..key.." value")
end
local myTb = Set:new({name = "Mical", age = })
myTb.sex = "man" 结果:
can't set sex value

rawset(t, k, v):

  不调用任何的metamethod 对表t的k域赋值为v,上述例子就可以用rawset(myTb, "sex", "man")赋值。

给表设置默认值:

 local key = {}
local mt = {__index = function(t) return t[key] end}
function setDefault(t, d)
t[key] = d
setmetatable(t, mt)
end

监控表: 

index用于查询,__newindex用于更新,它们都是在访问的域不存在的时候才起作用。如果我们想捕获对一个表的所有反问,可以通过保持这个表为空来实现。

 local index = {}
local mt = { __index = function(t, k)
print("access to element "..tostring(k))
return t[index][k]
end,
__newindex = function(t, k, v)
print("update of element "..tostring(k).." to "..tostring(v))
t[index][k] = v
end
}
local function track(t)
local proxy = {}
proxy[index] = t
setmetatable(proxy, mt)
return proxy
end local myTb = {}
local nowTb = track(myTb)
nowTb.name = "mical"
print(nowTb.name) nowTb.age =
print(nowTb.sex) for k, v in pairs(nowTb) do
print(k, "\n", v);
end

lua的Metatables和Metamethods的更多相关文章

  1. Lua 与 Redis

    Lua 与 Redis 标签: Java与NoSQL 从 2.6版本 起, Redis 开始支持 Lua 脚本 让开发者自己扩展 Redis - 案例-实现访问频率限制: 实现访问者 $ip 在一定的 ...

  2. [转]LUA元表

    lua元表和元方法 <lua程序设计> 13章 读书笔记 lua中每个值都有一个元表,talble和userdata可以有各自独立的元表,而其它类型的值则共享其类型所属的单一元表.lua在 ...

  3. Lua.LearningLua.7-userdata

    Learning Lua: 7 - userdata 1. Userdata basic "There are eight basic types in Lua: nil, boolean, ...

  4. 初识lua

    转自:http://www.oschina.net/question/12_115993-- 两个横线是单行注释(译者注:这跟 SQL 一样) --[[ 增加两个 [ 和 ] 变成多行注释 我是多行注 ...

  5. lua学习

    在lua中,一切都是变量,除了关键字. 1.注释: 单行注释: 连续两个减号“--”表示注释的开始,一直延续到行末.相当于C语言中的“//” 多行注释:由“--[[”表示注释开始, “]]”表示注释结 ...

  6. Lua语言模型 与 Redis应用

    Lua语言模型 与 Redis应用 标签: Java与NoSQL 从 2.6版本 起, Redis 开始支持 Lua 脚本 让开发者自己扩展 Redis. 本篇博客主要介绍了 Lua 语言不一样的设计 ...

  7. Learn Lua in 15 Minutes

    原文地址:http://tylerneylon.com/a/learn-lua/ Learn Lua in 15 Minutes more or less For a more in-depth Lu ...

  8. Redis结合Lua脚本实现高并发原子性操作

    从 2.6版本 起, Redis 开始支持 Lua 脚本 让开发者自己扩展 Redis … 案例-实现访问频率限制: 实现访问者 $ip 在一定的时间 $time 内只能访问 $limit 次. 非脚 ...

  9. 15分钟入门lua

    目录:[ - ] -- 1. Variables and flow control. -- 2. Functions. -- 3. Tables. -- 3.1 Metatables and meta ...

随机推荐

  1. 【第二课】kaggle案例分析二

    Evernote Export 推荐系统比赛(常见比赛) 推荐系统分类 最能变现的机器学习应用 基于应用领域分类:电子商务推荐,社交好友推荐,搜索引擎推荐,信息内容推荐等 **基于设计思想:**基于协 ...

  2. Spring Cloud Alibaba、Spring Boot、Spring Cloud对应版本关系

    Spring Boot Spring Cloud Spring Cloud Alibaba 2.1.x Greenwich 0.9.x 2.0.x Finchley 0.2.x 1.5.x Edgwa ...

  3. pytorch基础(4)-----搭建模型网络的两种方法

    方法一:采用torch.nn.Module模块 import torch import torch.nn.functional as F #法1 class Net(torch.nn.Module): ...

  4. 洛谷P1579 哥德巴赫猜想(升级版)【水题+素数】

    1742年6月7日哥德巴赫写信给当时的大数学家欧拉,正式提出了以下的猜想:任何一个大于9的奇数都可以表示成3个质数之和.质数是指除了1和本身之外没有其他约数的数,如2和11都是质数,而6不是质数,因为 ...

  5. 4.IntelliJ Idea 常用快捷键

    IntelliJ Idea 常用快捷键列表 Ctrl+Shift + Enter,语句完成“!”,否定完成,输入表达式时按 “!”键Ctrl+E,最近的文件Ctrl+Shift+E,最近更改的文件Sh ...

  6. java 反射之获取泛型对象的所有字段与对应的值(包括父类的)

    上代码: public static void main(String[] args) throws IntrospectionException { SysUser obj = new SysUse ...

  7. lunix下的redis数据库操作——list列表

    首先,需要先了解栈和队列的概念: 栈  先进后出:类比弹夹上的子弹,最后上进弹夹的子弹第一个使用,砌墙的板砖,后来居上 队列  先进先出:排队打饭,先到先得 创建列表: 左添加:(栈的形式添加) lp ...

  8. Nexus私服的搭建

    1.nexus 介绍     是开源的,用该框架架设maven私有服务器   2.nexus私服环境搭建     把nexus.war包放到tomcat的webapps下面     浏览且登录     ...

  9. hdu 1568关于斐波那契数列的公式及其思维技巧

    先看对数的性质,loga(b^c)=c*loga(b),loga(b*c)=loga(b)+loga(c); 假设给出一个数10234432,那么log10(10234432)=log10(1.023 ...

  10. 【微信小程序】:小程序,新场景

    前言: 我们频繁进入的地方,是场景. 手机.是场景:浏览器.是场景.事实上,微信,也是场景-- 微信要做的是占领很多其它用户时间.占领很多其它应用场景.占领很多其它服务入口.这是商业本质想去垄断要做的 ...