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 ...
随机推荐
- JAVA之HashMap集合
/** * HashMap集合讲解 * HashMap集合不允许集合元素的Key重复 */package com.test; import java.util.*; public class test ...
- [转] docker rmi命令-删除image
原文:http://www.simapple.com/341.html ---------------------------------------------------------------- ...
- Elasticsearch教程(三),IK分词器安装 (极速版)
如果只想快速安装IK,本教程管用.下面看经过. 简介: 下面讲有我已经打包并且编辑过的zip包,你可以在下面下载即可. 当前讲解的IK分词器 包的 version 为1.8. 一.下载zip包. 下面 ...
- MSSQL注入SA权限不显错模式下的 入 侵
一般新手扫到不显错的SA(systemadmin)的注入点时,虽然工具能猜表列目录但还是很麻烦有的人就直接放弃了,今天我给大家演示下如何利用.方法很简单大家看操作. 我这里使用的是 火狐的插件提交参数 ...
- Laravel之任务调度
一.基本简介 任务调度定义在app/Console/Kernel.php 文件的schedule 方法中,该方法中已经包含了一个示例.你可以自由地添加你需要的调度任务到Schedule 对象. 二.开 ...
- Ubuntu升级出现/boot空间不足解决(转)
经常升级Linux内核,导致更新时警告/boot分区空间不足.这是以为多次升级内核后,导致内核版本太多,清理一下没用的内核文件就行了.命令如下: zht@zht-Ubuntu:~$ dpkg -l ' ...
- sprint3 【每日scrum】 TD助手站立会议第十天
站立会议 组员 昨天 今天 困难 签到 刘铸辉 (组长) 团队进入最终的功能测试阶段,准备发布Beta版 和团队发布Beta版,并开总结会议 总结会议 Y 刘静 团队集合软件测试 软件发布 没有 Y ...
- [分享]windows下编译squid的经验(转)
squid是什么我这里就不说了,这不是本文的重点,总之它是一个集:代理.加速.缓存.负载均衡.防盗链.访问控制等多功能的一个超牛X开源软件,如今已经广泛应用于很多领域.对于缓存和加速这一领域,如今各大 ...
- 【HBase基础教程】1、HBase之单机模式与伪分布式模式安装(转)
在这篇blog中,我们将介绍Hbase的单机模式安装与伪分布式的安装方式,以及通过浏览器查看Hbase的用户界面.搭建hbase伪分布式环境的前提是我们已经搭建好了hadoop完全分布式环境,搭建ha ...
- Atitit.5gl 第五代语言编程语言 PROLOG教程 人工智能语言的标准 与实现
Atitit.5gl 第五代语言编程语言 PROLOG教程 人工智能语言的标准 与实现 1. 第五代语言就是自然语言又被称为知识库语言或人工智能语言,1 2. 人工智能语言特点2 2.1. 试探法2 ...