Lua只读表
利用Lua的元表(metatable)和元函数(metafunction)可以很简单的实现此功能。
其实现大致分为三个部分
- 1.禁止在表中创建新值
- 2.禁止改变已有的值
- 3.将子表也变为只读
1.禁止在表中创建新值
使用__newindex元函数即可,它的作用就是在表赋新值时调用
local static = {
exist={exist={exist=true}},
}
setmetatable(static, {__newindex = function() assert(false, 'table is readonly\n') end})
static['not-exist'] = false
这样给只读表赋一个新值,就会报错了

2.禁止改变已有的值
这一项功能没有元函数直接提供,可以通过另一个方法巧妙的实现
原理:将传入的表作为返回表的元表__index,这样如果你想要改变值,就会转化为赋新值,这样就会调用元表的__newindex
local readonly = function(t)
local meta = {
__index = t,
__newindex = function() assert(false, 'table is readonly\n') end,
}
local locked = {}
setmetatable(locked, meta)
return locked
end local static = {
exist={exist={exist=true}},
}
static = readonly(static)
static['exist'] = false
3.将子表也变为只读
此功能使用递归很好实现,只要对子表递归调用readonly函数即可。
local static = {
exist={exist={exist=true}},
}
local readonly
readonly = function(t, deep)
if deep then
for k,v in pairs(t) do
if type(v) == 'table' then
t[k] = readonly(v, deep)
end
end
end
local meta = {
__index = t,
__newindex = function() assert(false, 'table is readonly\n') end,
}
local locked = {}
setmetatable(locked, meta)
return locked
end
static = readonly(static, true)
static['exist']['exist']['exist'] = false
-- 打印表结构,如下图
print(inspect(static))
至此,readonly表就大成了,虽然其改变了表结果不过表用起来没什么变化
当前,它也存在问题,就是打印表不方便,很不直观,对调试可能会存在影响。
下面是使用inspect打印的表,看这样的表找字段数据,会有股蛋蛋的忧伤。。。

Lua只读表的更多相关文章
- Lua查找表元素过程(元表、__index方法是如何工作的)
近日开始研究Lua,在元表的使用上照猫画虎地搞了两下,实现了“面向对象”,但究其本质却略有不解,后咨询牛哥得解,特此记录. Lua的表本质其实是个类似HashMap的东西,其元素是很多的Key-Val ...
- lua弱表引用
1.普通垃圾回收 --lua弱表,主要是删除key或者value是table的一种元方法 --元表里的__mode字段包含k或者v:k表示key为弱引用:v表示value为弱引用 local test ...
- 利用__index和__newindex实现默认值表、监控表、只读表
__index和__newindex实际上相当于是在读写表的时候分别加了一道过滤的逻辑,让读写表的操作可以被监控或说回调,利用这个特性可以实现一些带有特殊功能的表. 带有默认值的表: setdefau ...
- C中调用LUA回调(LUA注册表)
实现原理: 通过将LUA中得回调函数存入LUA注册表中来保存LUA函数,然后在需要回调时从LUA注册表中取出LUA函数进行调用 下面是一些预备知识:(学习两个重要的函数) 原汁原味的英文解释的最透彻, ...
- 利用__index和__newindex实现默认值表、监控表、只读表(转)
__index和__newindex实际上相当于是在读写表的时候分别加了一道过滤的逻辑,让读写表的操作可以被监控或说回调,利用这个特性可以实现一些带有特殊功能的表. 带有默认值的表: setdefau ...
- lua table表
lua table表 语法结构 创建一个 table 直接使用 "{}" 即可 table1 = {} -- 赋值 table1["name"] = " ...
- 【游戏开发】小白学Lua——从Lua查找表元素的过程看元表、元方法
引言 在上篇博客中,我们简单地学习了一下Lua的基本语法.其实在Lua中有一个还有一个叫元表的概念,不得不着重地探讨一下.元表在实际地开发中,也是会被极大程度地所使用到.本篇博客,就让我们从Lua查找 ...
- Lua 读表代码,自动生成字段名字
表格格式为 INT STRING INT INT INT INT INT Id Desc Type SceneId OpenId MaxPliesp ClearancePlies 第1关 - 第2关 ...
- lua判断表中数据是否连续,0可以代表任何数
最近看到有lua面试题,挺有意思的,一张表中有若干个数,0可以代表任何数 比如有张表{9, 2, 4, 1, 3, 0, 0, 0, 0},按照规则这张表中的四个0可以用来代表5,6,7,8,那么这张 ...
随机推荐
- 1 RabbitMQ 安装,配置
1:安装 yum install -y rabbitmq-server 2:主要程序介绍 # 管理插件的程序 /usr/sbin/rabbitmq-plugins # 服务程序 /usr/sbin ...
- WebService(二)
使用eclipse开发webservice的服务器端以及客户端的简单实例 1.服务端 在eclipse中像建立一个web项目一样,new->Dynamic Web Project A.建一个需要 ...
- Vue.js 上传文件(后台使用.net)
页面部分 <div id="app"> <form id="myform"> <input type="file&quo ...
- 打印实例对象的名字 默认调用父类的toString 可重写
- Flume日志收集系统架构详解--转
2017-09-06 朱洁 大数据和云计算技术 任何一个生产系统在运行过程中都会产生大量的日志,日志往往隐藏了很多有价值的信息.在没有分析方法之前,这些日志存储一段时间后就会被清理.随着技术的发展和 ...
- 【数据库_Mysql】查询当前年份的sql
1.本年份 SELECT DATE_FORMAT(NOW(), '%Y'); 2.本月份(显示数字) SELECT DATE_FORMAT(NOW(), '%m'); 3.本月份(显示英文) SELE ...
- BZOJ3598 SCOI2014方伯伯的商场之旅(数位dp)
看到数据范围就可以猜到数位dp了.显然对于一个数最后移到的位置应该是其中位数.于是考虑枚举移到的位置,那么设其左边和为l,左右边和为r,该位置数为p,则需要满足l+p>=r且r+p>=l. ...
- 管理与技术未必不可兼得,一个20年IT老兵的码农生涯
作者|康德胜 我是一个喜欢写代码但几乎不太有机会写代码的CTO,也是一个看得懂财务报表.通过所有CFA(金融特许分析师)考试并获得FRM(金融风险经理)认证的拿到金融MBA的CTO,如果我有幸被称作码 ...
- DjangoORM创建表结构以及生成数据库结构
1. ORM的两种 DB first: 创建表结构--根据表结构生成类-----根据类来操作数据库 Code first: 先写代码------再写类----执行命令(一个类生成一个表)当前主流的用法 ...
- React Native工程中TSLint静态检查工具的探索之路
建立的代码规范没人遵守,项目中遍地风格迥异的代码,你会不会抓狂? 通过测试用例的程序还会出现Bug,而原因仅仅是自己犯下的低级错误,你会不会抓狂? 某种代码写法存在问题导致崩溃时,只能全工程检查代码, ...