Chapter 17_3 table的默认值
对象属性
有很多情况需要把有些属性绑定到某个对象,例如:函数与其名称、table的默认值、数组大小等...
当对象是一个table时,可以通过适当的key将属性存储在这个table中。
如果对象不是一个table,它就无法保存属性了。
另外,即使是table,有时也不想将属性存储在原table中。可以使用外部table来关联它们,将对象作为key,对象的属性作为value。
这个外部table可以保存任意对象的属性,Lua也允许将任何对象作为table的key。
另外,存储在外部对象中的属性不会干扰其他对象,只要table本身是私有的,这些属性也会是私有的。
然而,有一个缺陷,当用户将一个对象作为外部table的key时。就引用了它,Lua是无法回收一个作为table key的对象。
如果这个外部table关联函数和函数名,那么这些函数就永远无法回收。
可以用弱引用来解决这个问题。该情况使用的是弱引用key,当一个弱引用key没有其他引用时,Lua就回收它。
table的默认值
之前在table访问元方法一节最后提到过,用两种方法实现具有非nil默认值的table:一种是弱引用table,一种是备忘录。
它们其实就是之前讲到的备忘录和对象属性的特殊应用。
第一种方法:用一个弱引用table,通过它将每个table与其默认值关联起来:
local defaults = {}
setmetatable(defaults, { __mode = "k" } )
local mt = { __index = function(t) return defaults[t] end }
function setDefault ( t , d)
defaults[t] = d
setmetatable( t , mt )
end
如果defaults没有弱引用key,它就会使所有具有默认值的table持久存在下去。
第二种方法:对每种不同的默认值使用不同的元表,不过,只要有重复的默认值,就复用同样的元表。这是备忘录的典型应用:
local metas = {}
setmetatable(metas , {__mode = "v"})
function setDefault(t, d )
local mt = metas[d]
if mt == nil then
mt = {__index = function() return d end}
metas[d] = mt --备忘录
end
setmetatable(t , mt)
end
这里用到了弱引用value,这样当metas中的元表在不使用时就可以被回收了。
第一种的做法需要为每个table的默认值(defaults中的一个条目)使用内存。
第二种的做法需要为每个不同的默认值使用一组内存(一个新table、一个新closure和metas中的一个条目)。
如果程序上有上千个table和一些默认值,第二种是首选;但是只有很少的table共享几个公用的默认值,就选第一种。
以上内容来自:《Lua程序设计第二版》和《Programming in Lua third edition 》
Chapter 17_3 table的默认值的更多相关文章
- chapter 13_3 table访问的元方法
前两节的算术类.关系类运算符的元方法都为各种错误情况定义了行为,它们不会改变语言的常规行为. 但是Lua还提供了两种可以改变table行为的方法: 一种是查询table中不存在的字段.一种是修改tab ...
- (转载)JAVA中八种基本数据类型的默认值
原文链接: http://simon-c.iteye.com/blog/1016031 引用 For type byte, the default value is zero, that is, th ...
- 慎用create table as select,一定要注意默认值的问题
再做一些数据迁移时候,很多人会使用create table as select * from table where id=-1的方式来年建立一摸一样的表,但是这样做有个很大的弊端,不能将原表中的d ...
- PowerDesigner 怎么给 Table Properties 增加注释和默认值
1. 选中表,右键 2. 选中“comment”, 这个就是列的注释 3.还是这个页面 ,往下有个“default value”, 这个就是你设置的默认值. 4. 这个是怎么设置默认值.
- [转]Hibernate设置时间戳的默认值和更新时间的自动更新
原文地址:http://blog.csdn.net/sushengmiyan/article/details/50360451 Generated and default property value ...
- Hibernate设置时间戳的默认值和更新时间的自动更新
Generated and default property values 生成的和默认的属性值 The database sometimes generates a property value, ...
- Entity Framework 6 Recipes 2nd Edition(12-7)译 -> 设定默认值
12-7. 设定默认值 问题 在把一个实体保存到数据库之前,设置该实体属性的默认值 解决方案 假设你有一个如Figure 12-9所示的表, 它保存采购订单(purchase order). 主键Pu ...
- sql 修改字段默认值
1.查出该字段的约束名称 SELECT c.name FROM sysconstraints a INNER JOIN syscolumns b on a.colid=b.colid INNER JO ...
- ASP.NET MVC 让@Html.DropDownList显示默认值
在使用@Html.DropDownList的过程中,发现它的用法很局限,比如在加载的时候显示设定的默认项或者调整它的显示样式,在网上查了一些资料,终于把这个问题解决了. 一.View代码 @using ...
随机推荐
- YARN之上的大数据框架REEF:微软出品,是否值得期待?
YARN之上的大数据框架REEF:微软出品,是否值得期待? 摘要:微软即将开源大数据框架REEF,REEF运行于Hadoop新一代资源管理器YARN的上层.对于机器学习等在数据传输.任务监控和结果 ...
- ASP.NET MVC 之View
仅此一文让你明白ASP.NET MVC 之View的显示(仅此一文系列二) 题外话 一周之前写的<仅此一文让你明白ASP.NET MVC原理>受到了广大学习ASP.NET MVC同学的 ...
- 竞价广告系统-逻辑回归优化方法-L-BFGS
逻辑回归优化方法-L-BFGS 逻辑回归的优化方法是一个经典的问题,如果我们把它视为一个最大熵模型,那么我们知道最早的优化方法是IIS,这个方法就不细讲了,因为它速度很慢.后来发现在最优化领域中非常常 ...
- 探讨C++ 变量生命周期、栈分配方式、类内存布局、Debug和Release程序的区别
探讨C++ 变量生命周期.栈分配方式.类内存布局.Debug和Release程序的区别(一) 今天看博客园的文章,发现博问栏目中有一个网友的问题挺有趣的,就点进去看了下,标题是“C++生存期问题”,给 ...
- OpenGL屏幕二维坐标转化成三维模型坐标
我们把OpenGL里模型的三维坐标往二维坐标的转化称为投影,则屏幕上的二维坐标往三维坐标转化则可以称为反投影,下面我们来介绍一下反投影的方法. 主要是gluUnProject函数的使用,下面是代码: ...
- poj1483 It's not a Bug, It's a Feature!
It's not a Bug, It's a Feature! Time Limit: 5000MS Memory Limit: 30000K Total Submissions: 1231 ...
- 怎样求FIRST集、FOLLOW集和SELECT集
一,要知道什么是终结符和非终结符. 终结符:通俗的说就是不能单独出现在推导式左边的符号,也就是说终结符不能再进行推导. 非终结符:不是终结符的都是非终结符.(非男即女,呵呵) 如:A-->B,则 ...
- 使用gulp构建自动化工作流
简单易用 高效构建 高质量的生态圈 可能很多人会说现在提gulp也太落后了吧,但我想说写点东西并不是为了讨论它是否过时,而是来帮助我们自己来记忆.整理和学习.任何工具,我需要,我才去使用它,正如此时我 ...
- 微信JSAPI支付 跟 所遇到的那些坑
首先介绍一下我在调用微信支付接口使用的是 weixin.senparc SDK,非常方便好用开源的一个微信开发SDK. weixin.senparc SDK 官网:http://weixin.senp ...
- .net 实战 根据configuration选项生成不同的config文件
项目开发过程中都会遇到的问题,开发环境的配置肯定是和生产环境不一样的,一直都是重复手动拷贝,但是配置太多拷贝的弊端就显现出来了,为了解决这个问题可以有几种方案: 1.Web.config Transf ...