__index和__newindex实际上相当于是在读写表的时候分别加了一道过滤的逻辑,让读写表的操作可以被监控或说回调,利用这个特性可以实现一些带有特殊功能的表。

  带有默认值的表:

setdefault = function(t, v)
setmetatable(t, {__index = function () return v end})
end s = {1, 2, 3}
setdefault(s, 0) -- 默认值设为0
print(s.x)

  一般访问不存在的域会返回nil,但经过上面代码处理后,访问不存在的域会返回一个默认值。为了实现公用metatable,可以将代码封装如下:

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

  监控表(代理表):

t = {} --需要监控的表
local _t = t
t = {} --代理表需要为空,因为只有当读写不存在的域时,才会触发__index和__newindex local mt = {
__index = function (t, k)
print("*access to element"..tostring(k))
return _t[k]
end, __newindex = function(t, k, v)
print("*update of element " .. tostring(k) .. " to " .. tostring(v))
_t[k] = v
end
} setmetatable(t, mt) t[2] = 'hello'
print(t[2])

  对上述代码进行一些适当的封装,将原始表作为代理表的一个特殊的域对应的值:

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
} track = function (t)
local proxy = {}
proxy[index] = t
setmetatable(proxy, mt)
return proxy
end t = track(t)

  只读表:

function readOnly(t)
local proxy = {}
local mt = {
__index = t,
__newindex = function (t, k, v)
error("attemp to uopdaate a read-only table", 2)
end
} setmetatable(proxy, mt)
return proxy
end days = readOnly{"Sunday", "Monday", "Tuesday", "Wednesday","Thursday", "Friday", "Saturday"}
print(days[1])
days[2] = "Noday"

  上述利用__index和__newindex特性来实现的一些具有特殊表的方法都比较简单易懂,而且很好用。

http://www.cnblogs.com/sifenkesi/p/3837944.html

利用__index和__newindex实现默认值表、监控表、只读表(转)的更多相关文章

  1. 利用__index和__newindex实现默认值表、监控表、只读表

    __index和__newindex实际上相当于是在读写表的时候分别加了一道过滤的逻辑,让读写表的操作可以被监控或说回调,利用这个特性可以实现一些带有特殊功能的表. 带有默认值的表: setdefau ...

  2. Lua中__index和__newindex实践

    [具有默认值的table] 我们都知道,table中的任何字段的默认值都是nil,但是通过元表,我们可以很容易的修改这一规定,代码如下: function setDefault(tb, default ...

  3. Spring Cloud实战之初级入门(四)— 利用Hystrix实现服务熔断与服务监控

    目录 1.环境介绍 2.服务监控 2.1 加入依赖 2.2 修改配置文件 2.3 修改启动文件 2.4 监控服务 2.5 小结 3. 利用hystrix实现消费服务熔断 3.1 加入服务熔断 3.2 ...

  4. C# DateTime的11种构造函数 [Abp 源码分析]十五、自动审计记录 .Net 登陆的时候添加验证码 使用Topshelf开发Windows服务、记录日志 日常杂记——C#验证码 c#_生成图片式验证码 C# 利用SharpZipLib生成压缩包 Sql2012如何将远程服务器数据库及表、表结构、表数据导入本地数据库

    C# DateTime的11种构造函数   别的也不多说没直接贴代码 using System; using System.Collections.Generic; using System.Glob ...

  5. 驱动开发:内核监控Register注册表回调

    在笔者前一篇文章<驱动开发:内核枚举Registry注册表回调>中实现了对注册表的枚举,本章将实现对注册表的监控,不同于32位系统在64位系统中,微软为我们提供了两个针对注册表的专用内核监 ...

  6. 利用jquery.validate以及bootstrap的tooltip开发气泡式的表单校验组件

    表单校验是页面开发中非常常见的一类需求,相信每个前端开发人员都有这方面的经验.网上有很多成熟的表单校验框架,虽然按照它们默认的设计,用起来没有多大的问题,但是在实际工作中,表单校验有可能有比较复杂的个 ...

  7. 数据库级别DML操作监控审计、表触发器/对象触发器

    使用触发器记录DML,使用触发器记录表的DML 数据库级别DML操作监控审计.表触发器/对象触发器 --创建记录表 CREATE TABLE T_SHALL_LOG ( ID , ) , EVTIME ...

  8. C# 利用mysql.data 在mysql中创建数据库及数据表

    C# 利用mysql.data 在mysql中创建数据库及数据表 using System; using System.Collections.Generic; using System.Linq; ...

  9. 利用网络流传的WebShell默认密码库寻找WebShell

    声明:本文提到的技术,仅可用作网络安全加固等合法正当目的.本文作者无法鉴别判断读者阅读本文的真实目的,敬请读者在本国法律所允许范围内阅读本文,读者一旦因非法使用本文提到技术而违反国家相关的法律法规,所 ...

随机推荐

  1. Ubuntu 12.04更新源

    源地址:http://www.cnblogs.com/eastson/archive/2012/08/24/2654163.html 1.首先备份Ubuntu12.04源列表 sudo cp /etc ...

  2. 初步C++运算符重载学习笔记&lt;3&gt; 增量递减运算符重载

    初步C++运算符重载学习笔记<1> 初探C++运算符重载学习笔记<2> 重载为友元函数     增量.减量运算符++(--)分别有两种形式:前自增++i(自减--i).后自增i ...

  3. GitHub基本操作(转)

    一.上传代码到仓库 步骤一:创建本地仓库,如下: 创建结果: 步骤二:发布自己创建的仓库,如下: 发布完显示如下: 步骤三:向自己发布仓库上传代码,如下: 首先将代码复制到本地仓库,如下: 复制完,显 ...

  4. hdu1292(递推dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1292 分析:    i代表人数,j代表组数,有dp[i][j]=dp[i-1][j-1]+dp[i-1 ...

  5. Drools学习笔记-01-在eclipse indgo集成Drools5.5

    1.1.条件 Drools它是一个基于Java开源规则引擎.因此,使用Drools以及前需要安装在开发机器JDK周边环境,Drools5.5需要JDK版本号的1.5或者更多. 1.2.开发环境搭建 大 ...

  6. hdu3966(树链剖分)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3966 题意:一颗树上,每个点有权值,定义三种操作: 1)I操作表示从a到b节点之间的节点都加上一个值 ...

  7. 单点更新线段树 RMQ

    D. Xenia and Bit Operations time limit per test 2 seconds memory limit per test 256 megabytes input ...

  8. hdu 1698 Just a Hook(线段树之 成段更新)

    Just a Hook                                                                             Time Limit: ...

  9. 打开或导入项目,从脱机 Outlook 数据文件 (.ost)

    打开或导入项目,从脱机 Outlook 数据文件 (.ost) Microsoft Outlook 2010 doesn\rquote t 支持手动打开或导入项目,从一个 脱机 Outlook 数据文 ...

  10. LeetCode——Valid Sudoku

    Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could be ...