lua 元表是个啥?
function readOnly(t)
local proxy = {}
local mt = {
__index = t,
__newindex = function(t,k,v)
error("attempt to update a read-only table")
end
}
setmetatable(proxy,mt)
return proxy
end days = readOnly{"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"}
print(days[])
days[] = "Noday"
—关于上面的只读表的运行过程解释
1:首先readOnly这个函数调用的说明,这个调用有点与其他语言不一样,参数没有放在圆括号中” 函数名() “,
而是直接跟了一个表的构造式,参看program in lua第五章 函数,最开始的前10句:
一个函数若只有一个参数,并且此参数是一个字面字符串或者是一个table构造式,那么圆括号是可有可无的.
days = readOnly{"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"}
2:readOnly(t) 的形参 t,接收了 {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday”}
那么相当于 t = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday”}
3:紧接着 local proxy = {} 是一个局部的表,且是空表,它的元表为mt,是因为 setmetatable(proxy,mt)这句话。
也就是说 proxy.__index = mt. __index这个字段是lua 为表内置的.
4:紧接着 return proxy 那么就相当于 days = proxy,记住 proxy是空表
5:print(days[1]) 相当于print(proxy[1]) ,但由于proxy[1]没有值,于是找它的元表 mt,而mt也没有 mt[1]对应的值,于是又找到__index 字段对应的值,于是就找到了之前t接收的匿名元表,然后就输出了Sunday,匿名元表就是{"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday”}
6:当对其赋值时,同第5步一样,最终找到了__newindex, 而它的值是一个函数,于是执行了
error("attempt to update a read-only table”)
7:上面的分析过程,就是lua解释这个脚本的过程,我们想象成,自己写了一个函数,当它接收那样一段脚本时,是像上面那样执行这么一个逻辑,把这么一个逻辑用一个概念总结,称之为元表,这就是元表的内函.
8:那为什么要这样做呢?这个逻辑,实际上是面向对象语言中的,多态的逻辑。只不过像C++,这样的语言,把上面的这种寻找过程的代码,由编译器产生而已。多态是相对继承而言的,即父类指针,指向了子类的对象,在运行时发生的行为,与代码给我们的字面逻辑不一致.
9:lua通过元表,来模拟面象对象的多态特性。
--输出结果为:
--[[
Sunday
lua: d:/test.lua:6: attempt to update a read-only table
stack traceback:
[C]: in function 'error'
d:/test.lua:6: in function <d:/test.lua:5>
d:/test.lua:15: in main chunk
[C]: ?
]]—
//-------------------------接下来分析一下 program in lua 第十三章的 13.1“算术类的元方法”------------------
把代码里加了点打印语句,就好理解了,另外把for语句省掉的部分写完整了。这样对照结果,就不会迷糊了。
对于初学者来说,原版书写的真是有点"不够厚道"。我看了N遍.才明白.不过省掉应该是为了少返回值,少执行一些代码,提高效率吧。
Set = {}
local mt ={}
function Set.new (l)
local set = {}
setmetatable(set, mt)
for _, v in ipairs(l) do
print("<",_,">","(",v,")")
set[v] = true
end
return set
end
function Set.union(a,b)
local res = Set.new{}
for k ,v in pairs(a) do res[k] = true print(k,res[k]) end
for k ,v in pairs(b) do res[k] = true print(k,res[k]) end
return res
end
function Set.intersection (a,b)
local res = Set.new{}
for k in pairs(a) do
res[k] = b[k]
end
return res
end
function Set.tostring (set)
local l = {}
for e ,v in pairs(set) do
print(e,"|----|", v)
l[#l + ] = e
end
return "{" .. table.concat(l,", ") .. "}"
end
function Set.print(s)
print(Set.tostring(s))
end
s1 = Set.new{,,,,}
s2 = Set.new{,}
print(getmetatable(s1))
print(getmetatable(s2))
mt.__add = Set.union
s3 = s1 +s2
print('-------')
print(s3)
print('-------')
Set.print(s3)
print(getmetatable(""))
for n in pairs(_G) do print(n) end
lua 元表是个啥?的更多相关文章
- [转]LUA元表
lua元表和元方法 <lua程序设计> 13章 读书笔记 lua中每个值都有一个元表,talble和userdata可以有各自独立的元表,而其它类型的值则共享其类型所属的单一元表.lua在 ...
- 学习Lua setmetatable Lua 元表
Lua 元表(Metatable) 在 Lua table 中我们可以访问对应的key来得到value值,但是却无法对两个 table 进行操作. 个人理解,这个相当于其他语言的继承,是把这个类的方法 ...
- Step By Step(Lua元表与元方法)
Step By Step(Lua元表与元方法) Lua中提供的元表是用于帮助Lua数据变量完成某些非预定义功能的个性化行为,如两个table的相加.假设a和b都是table,通过元表可以定义如何计算表 ...
- lua元表与元方法
lua中提供的元表(metatable)与元方法(metamethod)是一种非常重要的语法,metatable主要用于做一些类似于C++重载操作符式的功能. lua中提供的元表是用于帮助lua变量完 ...
- lua元表和元方法 《lua程序设计》 13章 读书笔记
lua中每个值都有一个元表,talble和userdata可以有各自独立的元表,而其它类型的值则共享其类型所属的单一元表.lua在创建table时不会创建元表. t = {} print(getmet ...
- lua元表
__index元方法:按照之前的说法,如果A的元表是B,那么如果访问了一个A中不存在的成员,就会访问查找B中有没有这个成员.这个过程大体是这样,但却不完全是这样,实际上,即使将A的元表设置为B,而且B ...
- <6>Lua元表和冒号 self
Lua中没有像C.C++.JAVA中的类概念,面向对象等 ,但我们可以模拟出来 1. Lua中有个很重要的概念元表 设置元表setmetatable()函数 获取元表getmetatable()函数 ...
- lua元表学习
a = {, } b= {, } vector2 = {} function vector2.Add(v1, v2) if(v1 == nil or v2 == nil)then return nil ...
- [转]lua元表代码分析
http://lin-style.iteye.com/blog/1012138 版本整理日期:2011/4/21 元表其实就是可以让你HOOK掉一些操作的一张表. 表的定义在ltm.h/c的文件里.对 ...
- lua元表详解
元表的作用 元表是用来定义对table或userdata操作方式的表 举个例子 local t1 = {1} local t2 = {2} local t3 = t1 + t2 我们直接对两个tabl ...
随机推荐
- IE常见BUG总结(持续更新)
ie6~7下display:inline-block无效 解决方案:需要hack触发hasLayout 1 //IE6.7中内联元素(如span)触发layout属性后, 它的行为和标准中的 inli ...
- tensorflow dynamic rnn源码分析
python3.6,tensorflow1.11 测试代码: tensorflow在eager模式下进行测试,方便调试,查看中间结果 import tensorflow as tf tf.enable ...
- 2017.7.27 logback配置文件
参考来自: Java深入 - logback的配置和使用 1 模块组成 logback分成三个模块:logback-core,logback- classic和logback-access. logb ...
- PHP防止sql注入-JS注入
一:为了网站数据安全,所有和数据库操作的相关参数必须做相关过滤,防止注入引起的网站中毒和数据泄漏 1.PHP自带效验函数 mysql_real_escape_string() 函数转义 SQL 语句中 ...
- hdu 5365 Run(BC 50 B题)(求四边形的个数)
本来准备睡觉.结果还是忍不住想把它A了.由于已经看了题解了, 题意:就是给你一些坐标.都是整数,求一些正多边形的数目,官方题讲解是地球人都知道整数坐标构不成正三角形.正五边形和正六边形的... 然而我 ...
- Step 2---有关Github的几个问题
1.取得项目的Git仓库的方式 第一种是在现存的目录下,通过导入所有文件来创建新的 Git 仓库. 要对现有的某个项目开始用 Git 管理,只需到此项目所在的目录,执行: $ git init 初始化 ...
- 【DB2】根据映射表映射出结果
第一步:创建语法 CREATE TABLE OLIVER_MAP(ID INT,COM_TYPE VARCHAR(100),COM_NAME VARCHAR(100),SR_UP DECIMAL(18 ...
- 网页抓取工具Teleport Ultra简介及如何使用
Teleport Ultra是一款专业的离线浏览器,能够快速.准确地从网络抓取数据并保存到本地,实现离线浏览的目的.它可以从Internet的任何地方抓回你想要的任何文件,它可以在你指定的时间自动登录 ...
- Android开发环境搭建 for windows (linux类似) 详细可参考“文件”中“Android开发环境搭建.pdf ”
ADT-Bundle for Windows 是由Google Android官方提供的集成式IDE,已经包含了Eclipse,你无需再去下载Eclipse,并且里面已集成了插件,它解决了大部分新手通 ...
- win10 microsoft edge 浏览器收藏夹位置
1.打开文件夹,找到(注意 用户名 改为你自己的用户名) C:\Users\用户名\AppData\Local\Packages\Microsoft.MicrosoftEdge_8wekyb3d8bb ...